码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P3293 [SCOI2016]美味

时间:2018-10-04 11:33:50      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:eps   gis   出现   min   span   \n   异或   namespace   bit   

传送门

异或最大值应该是要用\(trie\)树,从高位往低位贪心,虽然这里询问区间的数都要加上\(x\),但是仍然可以利用这个思想

从高往低位考虑,我们要找一个加上\(x\)后当前二进制位\(j\)不等于\(b\)的当前位的数,假设\(b\)当前位为0,我们就要现在找个数加上\(x\)后当前位\(j\)为1,记之前选出的数为\(ans\),那么我们就要找一个在\([ans+(1<<j)-x,ans+(1<<j)-(1<<j)-1-x]\)区间内的数;如果\(b\)当前位为1,那么取值范围为\([ans-x,ans-(1<<j)-1-x]\).如果有这个数,那么\(ans\)当前位\(j\)就可以等于\(b\)当前位\(xor\ 1\),否则就反过来

这个操作可以用主席树查询某区间的数出现次数的操作实现

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-7)

using namespace std;
const int N=500000+10;
const LL inf=1ll<<45;
il LL rd()
{
  re LL x=0,w=1;re char ch=0;
  while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  return x*w;
}

#define mid ((l+r)>>1)

int s[N*20],ch[N*20][2],rt[N],tt;
int n,m,kk,L,R,a[N];
il void inst(int p)
{
  rt[p]=++tt;
  int o1=rt[p],o2=rt[p-1],l=0,r=n;
  s[o1]=s[o2]+1;
  do
    {
      if(a[p]<=mid)
    {
      ch[o1][0]=++tt,ch[o1][1]=ch[o2][1];
      o1=ch[o1][0],o2=ch[o2][0],r=mid;
    }
      else
    {
      ch[o1][0]=ch[o2][0],ch[o1][1]=++tt;
      o1=ch[o1][1],o2=ch[o2][1],l=mid+1;
    }
      s[o1]=s[o2]+1;
    }
  while(l<r);
}
int quer(int o1,int o2,int l,int r,int ll,int rr)
{
  if(ll<=l&&r<=rr) return s[o1]-s[o2];
  int an=0;
  if(ll<=mid) an+=quer(ch[o1][0],ch[o2][0],l,mid,ll,rr);
  if(rr>mid) an+=quer(ch[o1][1],ch[o2][1],mid+1,r,ll,rr);
  return an;
}
bool ok(int l,int r,int ll,int rr)
{
  ll=max(ll,0),rr=min(rr,n);
  return ll<=rr?quer(rt[r],rt[l-1],0,n,ll,rr):0;
}
int q;

int main()
{
  ///no O2
  m=rd(),q=rd();
  for(int i=1;i<=m;i++) n=max(n,a[i]=rd());
  for(int i=1;i<=m;i++) inst(i);
  while(q--)
    {
      int b=rd(),x=rd(),ll=rd(),rr=rd(),ans=0;
      for(int i=17;i>=0;i--)
        {
          int nw=ans|(((b>>i&1)^1)<<i);
          if(ok(ll,rr,nw-x,nw+(1<<i)-1-x)) ans=nw;
          else ans|=(b>>i&1)<<i;
        }
      printf("%d\n",ans^b);
    }
  return 0;
}

luogu P3293 [SCOI2016]美味

标签:eps   gis   出现   min   span   \n   异或   namespace   bit   

原文地址:https://www.cnblogs.com/smyjr/p/9739276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!