标签:括号 size while 一段 记录 bsp clu names i++
Description
Solution
按位贪心,每次通过查询一段区间是否能够取到来判断这一位能否取最优解,主席树维护
(位运算的优先级真的非常低啊,尽量都加括号)
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #define N 100000 #define M 200005 using namespace std; int n,m,tot=0,rt[M],ls[M*20],rs[M*20],val[M*20]; int read() { int x=0,f=1;char c=getchar(); while(c<‘0‘||c>‘9‘){ if(c==‘-‘)f=-1;c=getchar(); } while(c>=‘0‘&&c<=‘9‘){ x=x*10+c-‘0‘;c=getchar(); } return x*f; } void insert(int &idx,int last,int l,int r,int v) { ++tot,idx=tot; ls[idx]=ls[last],rs[idx]=rs[last]; val[idx]=val[last]+1; if(l==r)return; int mid=(l+r)>>1; if(v<=mid)insert(ls[idx],ls[last],l,mid,v); else insert(rs[idx],rs[last],mid+1,r,v); } int query(int a,int b,int l,int r,int askl,int askr) { if(askl<=l&&askr>=r)return val[a]-val[b]; if(val[a]-val[b]==0)return 0; int mid=(l+r)>>1; if(askr<=mid)return query(ls[a],ls[b],l,mid,askl,askr); else if(askl>mid)return query(rs[a],rs[b],mid+1,r,askl,askr); else return query(ls[a],ls[b],l,mid,askl,askr)+query(rs[a],rs[b],mid+1,r,askl,askr); } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) { int a=read(); insert(rt[i],rt[i-1],1,N,a); } for(int i=1;i<=m;i++) { int b=read(),x=read(),l=read(),r=read(),ans=0; for(int j=17;j>=0;j--) { //ans记录aj+xi能取到的最优解 int L,R; if((1<<j)&b)L=ans,R=ans|(1<<j)-1; else L=ans|(1<<j),R=ans|((1<<(j+1))-1); L=max(L-x,0),R=min(R-x,N); if(L<=R&&query(rt[r],rt[l-1],1,N,L,R)) ans|=(1<<j)*(((b>>j)&1)^1); else ans|=(1<<j)*((b>>j)&1); } printf("%d\n",ans^b); } return 0; }
标签:括号 size while 一段 记录 bsp clu names i++
原文地址:http://www.cnblogs.com/Zars19/p/6910432.html