主席樹 模板題 luogu([POI2014]KUR-Couriers)


求區間內是否有個數大於二分之一的數,有的話輸出這個數,沒有的話輸出0.

在詢問的時候,如果左邊有sum大於這個limit,就可以繼續求,如果右邊有sum大於limit  也遞歸,

如果都不行,返回 0;

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<math.h>
 5 using namespace std;
 6 const int maxn=5e5+10;
 7 int Root[maxn],cnt;
 8 struct node
 9 {
10     int ln,rn,sum;
11 }tree[maxn*20];
12 void add(int &x,int y,int l,int r,int num)
13 {
14     tree[++cnt]=tree[y];tree[cnt].sum++;x=cnt;
15     if(l==r) return;
16     int mid=l+r>>1;
17     if(num<=mid) add(tree[x].ln,tree[y].ln,l,mid,num);
18     else add(tree[x].rn,tree[y].rn,mid+1,r,num);
19 }
20 int query(int x,int y,int l,int r,int limit)
21 {
22     if(l==r){
23         if(tree[x].sum-tree[y].sum>=limit) return l;
24         else return 0;
25     }
26     int left1=tree[x].ln,left2=tree[y].ln;
27     int right1=tree[x].rn,right2=tree[y].rn;
28     int mid=l+r>>1;
29     if(tree[left1].sum-tree[left2].sum>=limit){
30         return query(left1,left2,l,mid,limit);
31     }
32     else if(tree[right1].sum-tree[right2].sum>=limit){
33         return query(right1,right2,mid+1,r,limit);
34     }
35     else return 0;
36 }
37 int main()
38 {
39     int n,m;
40     scanf("%d%d",&n,&m);
41     for(int i=1;i<=n;i++){
42         int tmp;
43         scanf("%d",&tmp);
44         add(Root[i],Root[i-1],1,n,tmp);
45     }
46     for(int i=1;i<=m;i++){
47         int l,r;
48         scanf("%d%d",&l,&r);
49         int limit=(r-l+1)/2+1;
50         printf("%d\n",query(Root[r],Root[l-1],1,n,limit));
51     }
52     return 0;
53 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM