山由代码砌成。
总之就是WA82分调不出来,拿题解对拍也拍不出问题。
思路就是根据1的个数分类,然后用线段树维护。代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[100006];
struct tree
{
int l,r,huo[30],yu[30],pd[30],js[30];
}t[400006],ans;
int suan(int x)
{
int ans=0;
while(x) ans+=x&1,x/=2;
return ans;
}
void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r)
{
for(int i=0;i<=29;i++) t[x].yu[i]=INT_MAX,t[x].huo[i]=-1;
int xx=suan(a[l]);
t[x].pd[xx]=a[l],t[x].js[xx]=1;
for(int i=xx;i<=29;i++) t[x].huo[i]=a[l];
for(int i=xx;i>=0;i--) t[x].yu[i]=a[l];
return;
}
int mid=(l+r)/2;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
for(int i=0;i<=29;i++)
{
t[x].js[i]=t[x*2].js[i]+t[x*2+1].js[i];
t[x].yu[i]=t[x*2].yu[i]&t[x*2+1].yu[i];
if(t[x*2].huo[i]==-1) t[x].huo[i]=t[x*2+1].huo[i];
else if(t[x*2+1].huo[i]==-1) t[x].huo[i]=t[x*2].huo[i];
else t[x].huo[i]=t[x*2].huo[i]|t[x*2+1].huo[i];
if(t[x*2].pd[i]==-1||t[x*2+1].pd[i]==-1) t[x].pd[i]=-1;
else if(t[x*2].pd[i]!=t[x*2+1].pd[i])
{
if(t[x*2].pd[i]==0||t[x*2+1].pd[i]==0) t[x].pd[i]=t[x*2].pd[i]+t[x*2+1].pd[i];
else t[x].pd[i]=-1;
}
else t[x].pd[i]=t[x*2].pd[i];
}
}
void ask(int x,int l,int r)
{
if(l<=t[x].l&&t[x].r<=r)
{
for(int i=0;i<=29;i++)
{
ans.js[i]+=t[x].js[i];
ans.yu[i]&=t[x].yu[i];
if(t[x].huo[i]!=-1)
{
if(ans.huo[i]==-1) ans.huo[i]=t[x].huo[i];
else ans.huo[i]|=t[x].huo[i];
}
if(t[x].pd[i]==-1) ans.pd[i]=-1;
else if(t[x].pd[i]!=0)
{
if(ans.pd[i]==0) ans.pd[i]=t[x].pd[i];
else if(ans.pd[i]!=t[x].pd[i]) ans.pd[i]=-1;
}
}
return;
}
int mid=(t[x].l+t[x].r)/2;
if(l<=mid) ask(x*2,l,r);
if(r>mid) ask(x*2+1,l,r);
}
signed main()
{
//freopen("peace.in","r",stdin);
//freopen("peace.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
//for(int i=1;i<=10;i++) cout<<t[i].l<<' '<<t[i].r<<' '<<t[i].pd[2]<<endl;
//for(int i=1;i<=4;i++) cout<<t[i].l<<' '<<t[i].r<<' '<<t[i].huo[0]<<' '<<t[i].huo[1]<<' '<<t[i].huo[2]<<endl;
for(int i=1;i<=q;i++)
{
int l,r;
cin>>l>>r;
for(int j=0;j<=29;j++) ans.js[j]=ans.pd[j]=0,ans.huo[j]=-1,ans.yu[j]=INT_MAX;
ask(1,l,r);
//cout<<ans.huo[1]<<' '<<ans.huo[2]<<' '<<ans.huo[3]<<' '<<ans.huo[4]<<endl;
bool pd=0;
int huo,yu;
for(int j=0;j<=29;j++)
{
if(ans.pd[j]==-1) continue;
huo=-1,yu=INT_MAX;
if(j!=0&&ans.huo[j-1]!=-1)
{
if(huo==-1) huo=ans.huo[j-1];
else huo|=ans.huo[j-1];
}
if(j!=29) yu&=ans.yu[j+1];
//if(j==1) cout<<ans.js[j]<<endl;
if(huo==-1)
{
if(ans.js[j]==0) continue;
ans.js[j]--,huo=ans.pd[j];
}
if(yu==INT_MAX)
{
if(ans.js[j]==0) continue;
ans.js[j]--,yu&=ans.pd[j];
}
//cout<<j<<' '<<huo<<' '<<yu<<' '<<ans.js[j]<<endl;
if(ans.js[j]==0&&yu==huo||ans.js[j]>=1&&((yu&ans.pd[j])==huo||yu==(huo|ans.pd[j]))||ans.js[j]>=2&&(yu&ans.pd[j])==(huo|ans.pd[j]))
{
pd=1;
break;
}
}
if(pd) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
/*
6 1
2 7 8 2 9 7
2 4
*/