BZOJ 4571: [Scoi2016]美味

来源:互联网 发布:重叠覆盖优化案例 编辑:程序博客网 时间:2024/04/28 16:37

区间最大异或对,显然用可持久化Trie嘛

WTF???怎么轻易地就加了一个数呢

好吧我们考虑把Trie的每个节点加上个值域,于是就变成了主席树啦

于是从高位往低位贪心,每次找到该位异或为1时可选的区域,在主席树上找区域中是否存在值

复杂度mlogwlogw

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<algorithm>#include<map>#include<set>#include<stack>#include<cstdlib>#include<ctime>#define rep(i,l,r) for(int i=l;i<=r;i++)#define per(i,r,l) for(int i=r;i>=l;i--)#define mmt(a,v) memset(a,v,sizeof(a))#define tra(i,u) for(int i=head[u];i;i=e[i].next)using namespace std;const int N=200000+5;const int M=100000-1;int w[N*25],ch[N*25][2],sz,root[N];void insert(int &x,int l,int r,int p){sz++;w[sz]=w[x];ch[sz][0]=ch[x][0];ch[sz][1]=ch[x][1];x=sz;w[x]++;if(l==r)return;int mid=l+r>>1;if(p<=mid)insert(ch[x][0],l,mid,p);else insert(ch[x][1],mid+1,r,p);}int query(int x,int y,int l,int r,int a,int b){if(l==a&&b==r)return w[y]-w[x];int mid=l+r>>1;if(b<=mid)return query(ch[x][0],ch[y][0],l,mid,a,b);else if(mid<a)return query(ch[x][1],ch[y][1],mid+1,r,a,b);else return query(ch[x][0],ch[y][0],l,mid,a,mid)+query(ch[x][1],ch[y][1],mid+1,r,mid+1,b);}int main(){//freopen("a.in","r",stdin);int n,m;scanf("%d%d",&n,&m);rep(i,1,n){root[i]=root[i-1];int x;scanf("%d",&x);insert(root[i],0,M,x);}while(m--){int b,x,l,r;scanf("%d%d%d%d",&b,&x,&l,&r);int ans=0;per(i,18,0){int s,t;if(b>>i&1)s=ans,t=ans+(1<<i)-1;else s=ans+(1<<i),t=ans+(1<<i+1)-1;s=max(s-x,0);t=min(t-x,M);if(s<=t&&query(root[l-1],root[r],0,M,s,t))ans+=(1<<i)*((b>>i&1)^1);else ans+=(1<<i)*(b>>i&1);}printf("%d\n",ans^b);}return 0;}



0 0
原创粉丝点击