C. 攀登山峰
链接:https://nanti.jisuanke.com/t/49111
题意:求区间范围内出现次数大于k的所有数字中最大的数字,如果没有输出-1
思路:直接建立主席树,因为题目给出的t的范围很小,所以可以query部分直接判断也不会超时
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 int a[maxn]; 6 int b[maxn]; 7 int now; 8 int root[maxn]; 9 int cnt; 10 int ans; 11 struct node 12 { 13 int ln,rn; 14 int sum; 15 }tree[maxn*30]; 16 void build(int &x,int l,int r) 17 { 18 ++cnt;x=cnt; 19 if(l==r){ 20 tree[cnt].sum=0; 21 return; 22 } 23 int mid=l+r>>1; 24 build(tree[x].ln,l,mid); 25 build(tree[x].rn,mid+1,r); 26 tree[x].sum=tree[tree[x].ln].sum+tree[tree[x].rn].sum; 27 } 28 void update(int &x,int y,int pos,int l,int r) 29 { 30 cnt++;x=cnt; 31 tree[cnt]=tree[y]; 32 if(l==r){ 33 tree[cnt].sum++; 34 return; 35 } 36 int mid=l+r>>1; 37 if(pos<=mid) update(tree[cnt].ln,tree[y].ln,pos,l,mid); 38 else update(tree[cnt].rn,tree[y].rn,pos,mid+1,r); 39 tree[x].sum=tree[tree[x].ln].sum+tree[tree[x].rn].sum; 40 } 41 void query(int x,int y,int base,int l,int r) 42 { 43 if(tree[y].sum-tree[x].sum<=base) return; 44 if(l==r){ 45 ans=max(ans,b[l]); 46 return; 47 } 48 int mid=l+r>>1; 49 query(tree[x].ln,tree[y].ln,base,l,mid); 50 query(tree[x].rn,tree[y].rn,base,mid+1,r); 51 } 52 int main() 53 { 54 int n,m; 55 scanf("%d%d",&n,&m); 56 for(int i=1;i<=n;i++){ 57 scanf("%d",&a[i]); 58 b[i]=a[i]; 59 } 60 sort(b+1,b+1+n); 61 int limit=unique(b+1,b+1+n)-b-1; 62 build(root[0],1,limit); 63 for(int i=1;i<=n;i++){ 64 int tmp=lower_bound(b+1,b+1+limit,a[i])-b; 65 update(root[i],root[i-1],tmp,1,limit); 66 } 67 while(m--){ 68 int t1,t2,t3; 69 scanf("%d%d%d",&t1,&t2,&t3); 70 int base=(t2-t1+1)/t3; 71 ans=-1; 72 query(root[t1-1],root[t2],base,1,limit); 73 printf("%d\n",ans); 74 } 75 return 0; 76 77 }