标签:== trie树 pen using define space return i++ div
首先想到建出可持久化trie树然后在上面贪心,但是它加了一个数所以不能这么做
但依然可以贪心,仿照上面那个的过程,如果设y是在第i位上^b是1的数(前面的位数已经贪好了),我只要在[l,r]范围内能有[y-x,y+(1<<i)-x-1)]的数,那这位异或出来就是可以是1的
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=2e5+10,maxp=maxn*20; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=-1;c=getchar();} 11 while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar(); 12 return x*neg; 13 } 14 15 int root[maxn],N,M,L=100000; 16 int ch[maxp][2],v[maxp],pct; 17 18 void insert(int pre,int &p,int l,int r,int x){ 19 p=++pct; 20 v[p]=v[pre]+1; 21 if(l<r){ 22 int m=l+r>>1; 23 if(x<=m) ch[p][1]=ch[pre][1],insert(ch[pre][0],ch[p][0],l,m,x); 24 else ch[p][0]=ch[pre][0],insert(ch[pre][1],ch[p][1],m+1,r,x); 25 } 26 } 27 28 int query(int pre,int p,int l,int r,int x,int y){ 29 if(x<=l&&r<=y) return v[p]-v[pre]; 30 int m=l+r>>1,re=0; 31 if(x<=m) re=query(ch[pre][0],ch[p][0],l,m,x,y); 32 if(y>=m+1) re+=query(ch[pre][1],ch[p][1],m+1,r,x,y); 33 return re; 34 } 35 36 inline int solve(int b,int x,int pre,int p){ 37 int n=0; 38 for(int i=17;i>=0;i--){ 39 int y=n|((((b>>i)&1)^1)<<i); 40 // printf("%d %d\n",n,y); 41 if(query(pre,p,0,L,max(0,y-x),min(L,y+(1<<i)-x-1))) n=y; 42 else if((b>>i)&1) n|=(1<<i); 43 } 44 return n^b; 45 } 46 47 int main(){ 48 //freopen("","r",stdin); 49 int i,j,k; 50 N=rd();M=rd(); 51 for(i=1;i<=N;i++){ 52 int a=rd(); 53 insert(root[i-1],root[i],0,L,a); 54 } 55 for(i=1;i<=M;i++){ 56 int b=rd(),x=rd(),l=rd(),r=rd(); 57 printf("%d\n",solve(b,x,root[l-1],root[r])); 58 } 59 return 0; 60 }
bzoj4571/luogu3293 美味 (主席树+贪心)
标签:== trie树 pen using define space return i++ div
原文地址:https://www.cnblogs.com/Ressed/p/9782138.html