poj 3368 Frequent values 线段树

来源:互联网 发布:ubuntu lts什么意思 编辑:程序博客网 时间:2024/06/09 19:04

题意:给一个长度为n的不降序列a1,a2,a3,…,an,有q个询问,每个询问为:

i j
询问在子序列ai…aj中出现最多的元素。
数据范围:1 <= n, q <= 100000


分析:线段树每个节点记录该区间最长相同序列长度、从左边开始的相同序列长度和从右边开始的相同序列长度


代码:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;struct NODE{int l,r;int mx;int sl,sr;};NODE t[400001];int a[100001];void build(int d,int l,int r){t[d].l=l;t[d].r=r;if (l==r){t[d].mx=1;t[d].sl=1;t[d].sr=1;return;}int mid=(l+r)/2;build(d*2,l,mid);build(d*2+1,mid+1,r);t[d].sl=t[d*2].sl;t[d].sr=t[d*2+1].sr;t[d].mx=1;if (a[t[d*2].r]==a[t[d*2+1].l]){if (a[t[d*2].l]==a[t[d*2].r]) t[d].sl+=t[d*2+1].sl;if (a[t[d*2+1].l]==a[t[d*2+1].r]) t[d].sr+=t[d*2].sr;t[d].mx=t[d*2].sr+t[d*2+1].sl;}if (t[d*2].mx>t[d].mx) t[d].mx=t[d*2].mx;if (t[d*2+1].mx>t[d].mx) t[d].mx=t[d*2+1].mx;}int find(int d,int x,int y){if (t[d].l==x && t[d].r==y) return t[d].mx;int mid=(t[d].l+t[d].r)/2;if (y<=mid) return find(d*2,x,y);if (x>mid) return find(d*2+1,x,y);int f=max(find(d*2,x,mid),find(d*2+1,mid+1,y));if (a[t[d*2].r]==a[t[d*2+1].l]) f=max(f,min(mid-x+1,t[d*2].sr)+min(y-mid,t[d*2+1].sl));return f;}int main(){int n,m,x,y;while (1) {scanf("%d",&n);if (n==0) break;scanf("%d",&m);for (int i=1;i<=n;i++)scanf("%d",&a[i]);build(1,1,n);for (int i=1;i<=m;i++){scanf("%d%d",&x,&y);printf("%d\n",find(1,x,y));}}return 0;}


0 0
原创粉丝点击