从前有座山
查看原帖
从前有座山
712794
Azure_Space楼主2024/7/20 17:46

山由代码砌成。

总之就是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
*/
2024/7/20 17:46
加载中...