zoukankan      html  css  js  c++  java
  • 洛谷P3293 [SCOI2016]美味(主席树)

    传送门

    据说这题做法叫做可持久化trie树?(然而我并不会)

    首先考虑一下贪心,从高位到低位枚举,如果能选1肯定比选0优

    假设已经处理到了$b$的第$i$位,为1(为0的话同理就不说了)

    那么只有当$a_j+x$的第$i$位为0时才能让答案的第$i$位为$1$

    考虑把$x$的影响去掉。如果当前的答案是$ans$(即令前面几位贪心情况下最大且第$i$位为0时的$a$),那么只有在区间$[ans-x,ans+(1<<i)-1-x]$的数能在加上$x$之后第$i$位为0(这个可以自己手动算一算)

    如果存在,那么$ans$第$i$位变为0(存在前$i$位与之相同且第$i$位为0的$a_i$),否则变为1(只存在前$i$位与之相同且第$i$位为0的$a_i$)

    然后查找是两个区间限制主席树套上去就好了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     6 char buf[1<<21],*p1=buf,*p2=buf;
     7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
     8 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
     9 inline int read(){
    10     #define num ch-'0'
    11     char ch;bool flag=0;int res;
    12     while(!isdigit(ch=getc()))
    13     (ch=='-')&&(flag=true);
    14     for(res=num;isdigit(ch=getc());res=res*10+num);
    15     (flag)&&(res=-res);
    16     #undef num
    17     return res;
    18 }
    19 char sr[1<<21],z[20];int C=-1,Z;
    20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    21 inline void print(int x){
    22     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    23     while(z[++Z]=x%10+48,x/=10);
    24     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    25 }
    26 const int N=2e5+5,M=N*20;
    27 int rt[N],L[M],R[M],sum[M],a[N],cnt,n,q,m;
    28 void update(int &now,int last,int x,int l=0,int r=m){
    29     sum[now=++cnt]=sum[last]+1;
    30     if(l==r) return;
    31     int mid=(l+r)>>1;
    32     if(x<=mid) R[now]=R[last],update(L[now],L[last],x,l,mid);
    33     else L[now]=L[last],update(R[now],R[last],x,mid+1,r);
    34 }
    35 int query(int u,int v,int ql,int qr,int l=0,int r=m){
    36     if(ql<=l&&qr>=r) return sum[u]-sum[v];
    37     int mid=(l+r)>>1;
    38     if(ql<=mid&&query(L[u],L[v],ql,qr,l,mid)) return 1;
    39     if(qr>mid&&query(R[u],R[v],ql,qr,mid+1,r)) return 1;
    40     return 0;
    41 }
    42 inline int find(int u,int v,int ql,int qr){
    43     cmax(ql,0),cmin(qr,m);
    44     if(ql>qr) return 0;
    45     return query(rt[u],rt[v],ql,qr);
    46 }
    47 int main(){
    48 //    freopen("testdata.in","r",stdin);
    49     n=read(),q=read();
    50     for(int i=1;i<=n;++i) cmax(m,a[i]=read());
    51     for(int i=1;i<=n;++i)
    52     update(rt[i],rt[i-1],a[i]);
    53     while(q--){
    54         int b=read(),x=read(),ql=read(),qr=read(),ans=0;
    55         for(int i=17;i>=0;--i){
    56             int now=ans+((1^((b>>i)&1))<<i);
    57             if(find(ql-1,qr,now-x,now+(1<<i)-1-x)) ans=now;
    58             else ans+=((b>>i)&1)<<i;
    59         }
    60         print(ans^b);
    61     }
    62     Ot();
    63     return 0;
    64 }
  • 相关阅读:
    PMP工具与技术篇--4.2.1-4 思维导图(数据表现技术)
    PMP工具与技术篇--4.2.1-3 决策--多标准决策分析技术
    PMP工具与技术篇--4.2.1-2 决策--投票(举手表决)
    PMP工具与技术篇--4.2.1-1 标杆对照技术(数据收集技术)
    PMP工具与技术篇--4.2.1 收集需求工具与技术总结
    PMP--4.2.1-2 需求跟踪矩阵
    PMP--4.2.1-1 需求文件
    PMP--4.2.1 收集需求--需求文件--需求跟踪矩阵
    PMP工具与技术篇--4.2 备案分析(数据分析技术)
    PMP--4.2-2 开发方法
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9708512.html
Copyright © 2011-2022 走看看