给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。
标签:upd 建立 持久 inline 持久化 区间 name pre col
7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6
1
0
3
0
4
思路:建立可持久化权值线段树
AC代码:
#include <iostream> #include<cstdio> using namespace std; int x,n,m; int ls[10000010],rs[10000010],num[10000010],tot=0; int tree[500010]; inline void update(int pre,int& cur,int l,int r,int v){ cur=++tot; num[cur]=num[pre]+1; if(l==r) return; ls[cur]=ls[pre],rs[cur]=rs[pre]; int m=(l+r)>>1; if(v<=m) update(ls[pre],ls[cur],l,m,v); else update(rs[pre],rs[cur],m+1,r,v); } int ask(int ltree,int rtree,int k){ int l=1,r=n; while(l<r){ int m=(l+r)>>1; if(num[ls[rtree]]-num[ls[ltree]]>=k){ ltree=ls[ltree],rtree=ls[rtree]; r=m; } else if(num[rs[rtree]]-num[rs[ltree]]>=k){//区间内只可能有1个数出现次数超过一半 ltree=rs[ltree],rtree=rs[rtree]; l=m+1; } else return 0; } return l; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&x); update(tree[i-1],tree[i],1,n,x); } while(m--){ int l,r;scanf("%d%d",&l,&r); int ans=ask(tree[l-1],tree[r],(r-l+1)/2+1); printf("%d\n",ans); } return 0; }
标签:upd 建立 持久 inline 持久化 区间 name pre col
原文地址:https://www.cnblogs.com/lllxq/p/10184321.html