4571: [Scoi2016]美味

来源:互联网 发布:js设置div尺寸 编辑:程序博客网 时间:2024/06/11 18:39

4571: [Scoi2016]美味

主席树·位运算 的 奇妙世界

题解:

i[L,R],最大化:Xxor(A[i]+Y)

  • 如果我们先不考虑i[L,R]+Y呢?

    一个按位的二叉tire树可以解决问题。

    每次根据X的当前位决定优先向左还是向右,如果优先的一边没有点则走另一边。

    如果实际走的是优先选的那一边,ans=(ans<<1)+1,否则ans=ans<<1

  • 加上i[L,R]的限制?

    换上可持久化tire树即可。

  • 考虑+Y

    可持久化tire树就不行了。。。

    引用自:http://blog.csdn.net/neither_nor/article/details/51378123,有些许修改。

    考虑可持久化trie其实可以等价为一颗上限为2k1主席树,在trie上确定一位其实相当于将答案的区间缩小的一半,也就是在主席树上向下走一层

    当所有数加上Y之后,我们在主席树上走的时候看优先走的那一边有木有点就不能直接调用sz[son[x][0/1]],但是因为所有数都被加了,所以我们其实要查询的是优先走的区间向前窜Y位之后的区间有没有数,这样的话每次走的时候在主席树上重新查[l-Y,mid-Y]或者[mid+1-Y,r-Y]来判断应该往哪边走即可,复杂度多了个log,但是n=2*10^5,不虚。

讲真,我调了2h+

Code:

#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#define D(x) cout<<#x<<" = "<<x<<"  "#define E cout<<endl using namespace std;const int LOG = 18;const int N = 1<<LOG;int n,m,X,Y,L,R,ans,a[N],mx;int lch[N*20],rch[N*20],cnt[N*20],sz,root[N];void clone(int x,int t){    lch[x]=lch[t]; rch[x]=rch[t]; cnt[x]=cnt[t];}void insert(int &x,int t,int l,int r,int p){    x=++sz; clone(x,t); cnt[x]++;    if(l!=r){        int mid=(l+r)>>1;        if(p<=mid) insert(lch[x],lch[t],l,mid,p);        else insert(rch[x],rch[t],mid+1,r,p);    }}int query(int a,int b,int l,int r,int ql,int qr){    if(ql<=l && r<=qr){ return cnt[b]-cnt[a]; }    else{        int mid=(l+r)>>1, ans=0;        if(ql<=mid) ans+=query(lch[a],lch[b],l,mid,ql,qr);        if(qr>mid) ans+=query(rch[a],rch[b],mid+1,r,ql,qr);        return ans;    }}void solve(int l,int r,int bit){//  D(l); D(r); D(bit); D(ans); E;    if(l!=r){        int mid=(l+r)>>1;        if(X&(1<<bit)){//          D(max(l-Y,0)); D(max(mid-Y,0)); D(query(root[L-1],root[R],0,mx,max(l-Y,0),max(mid-Y,0))); E;            if(query(root[L-1],root[R],0,mx,max(l-Y,0),max(mid-Y,0))){ ans=(ans<<1)+1; solve(l,mid,bit-1); }            else{ ans=ans<<1; solve(mid+1,r,bit-1); }        }        else{//          D(max(mid+1-Y,0)); D(max(r-Y,0)); D(query(root[L-1],root[R],0,mx,max(mid+1-Y,0),max(r-Y,0))); E;            if(query(root[L-1],root[R],0,mx,max(mid+1-Y,0),max(r-Y,0))){ ans=(ans<<1)+1; solve(mid+1,r,bit-1); }            else{ ans=ans<<1; solve(l,mid,bit-1); }        }    }}int main(){    freopen("a.in","r",stdin);    scanf("%d%d",&n,&m);    mx=(1<<LOG)-1; //D(mx); E;    for(int i=1;i<=n;i++){ scanf("%d",a+i); }    for(int i=1;i<=n;i++){ insert(root[i],root[i-1],0,mx,a[i]); }    for(int i=1;i<=m;i++){        scanf("%d%d%d%d",&X,&Y,&L,&R);//      D(X); D(Y); E;        ans=0; solve(0,mx,LOG-1); printf("%d\n",ans);    }}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一多半宝宝爱喝水不爱吃饭怎么办 十个月宝宝不爱吃饭怎么办 十个月宝宝突然不爱吃饭怎么办 二十个月宝宝不爱吃饭怎么办 十个月的宝宝不爱吃饭怎么办 6年级学生数学差怎么办 打印机打不出来就是一张白纸怎么办 wps表格下拉数字不递增怎么办 wps表格圈怎么打出来怎么办 手表固定圈掉了怎么办 起来觉得头晕头胀怎么办? 孩子不好好写作业怎么办 孩子考试考差了怎么办 孩子计算题马虎大意怎么办 二年级孩子不认字怎么办 发现计算上的错误怎么办 孩子不好好做作业怎么办 手破了红肿了怎么办呢 老师反应孩子在校粗心胆小怎么办 四年级的学生计算粗心怎么办 老打孩子骂孩子怎么办 站久了脚肿了怎么办 孩子初中了书写越来越潦草怎么办 给孩子自由孩子无法无天怎么办 孩子挑食幼儿园老师该怎么办 老师说孩子挑食家长怎么办 工作中老是粗心不细心怎么办 小孩数学总是特别粗心该怎么办 孩子起范疙瘩的怎么办 做题马虎不认真怎么办 孩子考差了家长怎么办 小孩写作业不认真怎么办 小孩不认真检查作业怎么办 一年级的小孩作业不认真怎么办 一年级学生做题粗心怎么办 一年级的学生做题粗心怎么办 孩子做作业注意力不集中怎么办 小学三年孩子抄答案怎么办 孩子写作业不认真审题怎么办 一年级小孩审题不认真怎么办 孩子审题不认真马虎怎么办