MnZn 求调 5pts WA
查看原帖
MnZn 求调 5pts WA
701460
Magus楼主2025/1/10 20:10

PS:样例过了

BnB\ge n 应该挂不了,B<nB<n 的时候大概率会挂。

所以目测是外层 query 炸了,但是没找到错误。

// Problem:P5065 [Ynoi2014] 不归之人与望眼欲穿的人们
// Contest:Luogu
// URL:https://www.luogu.com.cn/problem/P5065
// Memory Limit:125 MB
// Time Limit:1000 ms
// Luogu Account:qhzx_FeS2_Butterfly
// Codeforces Account:Butterfly_qwq
// Atcoder Account:Super_agg
// CP Duel Rating:2007
// Start Coding:01-10 15:53
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int N=50004,B=224;
int n,m,blk[N],pos[N];
struct qu
{
    int sz,dat[35];
    inline int& operator [](const int& x){return dat[x];}
}ans[230];
void insert(qu u,int w,qu& t,int pos)
{
	t.sz=0;
	for(int i=0;i<31;i++)if(w&(1<<i))t[++t.sz]=(pos<<5)|i;
	for(int i=1;i<=u.sz;i++)if((~w)&(1<<(u[i]&31)))t[++t.sz]=u[i];
}
void merge(qu u,qu v,int w,qu& t)
{
	t.sz=0;
	for(int i=1;i<=u.sz;i++)if(w&(1<<(u[i]&31)))t[++t.sz]=u[i];
	for(int i=1;i<=v.sz;i++)if((~w)&(1<<(v[i]&31)))t[++t.sz]=v[i];
}
struct block
{
	int sz,val,lst,a[230],mx[230];qu pre[230],suf[230];
	inline int& operator [](const int& x){return a[x];}
	void getmax()
	{
		memset(mx,0xc0,sizeof(mx));
		for(int i=1;i<=sz;i++)for(int j=1,r=0,u;j<=pre[i].sz;j++)
		{
			r|=(1<<(pre[i][j]&31));
			u=i-(pre[i][j]>>5)+lst+1;
			mx[u]=max(mx[u],r);
		}
		for(int i=1;i<=sz;i++)mx[i]=max(mx[i],mx[i-1]);
	}
	void build()
	{
		for(int i=1;i<=sz;i++)val|=a[i];
		for(int i=1;i<=sz;i++)insert(pre[i-1],a[i],pre[i],lst+i);
		for(int i=sz;i;i--)insert(suf[i+1],a[i],suf[i],lst+i);
		getmax();
	}
	void update(int u,int w)
	{
		int inc=a[u]^w,r=0;a[u]=w;val=0;
		for(int i=1;i<=sz;i++)val|=a[i];
		insert(pre[u-1],a[u],pre[u],lst+u);
		for(int i=u+1;i<=sz;i++)
		{
			insert(pre[i-1],a[i],pre[i],lst+i);
			r|=a[i];if(r==(r|inc))break;
		}
		getmax();r=0;
		insert(suf[u+1],a[u],suf[u],lst+u);
		for(int i=u-1;i;i--)
		{
			insert(suf[i+1],a[i],suf[i],lst+i);
			r|=a[i];if(r==(r|inc))break;
		}
	}
	int query(int k,int R)
	{
		int l=1,r=min(sz+1,R),mid;
		while(l<r)
		{
			mid=l+r>>1;
			if(mx[mid]>=k)r=mid;
			else l=mid+1;
		}
		if(l==sz+1)return 0x3f3f3f3f;
		return l;
	}
}bl[230];
void init()
{
	for(int i=1;i<=n;i++){blk[i]=(i-1)/B+1;pos[i]=(i-1)%B+1;}
	for(int i=1;i<blk[n];i++)bl[i].sz=B;bl[blk[n]].sz=pos[n];
	for(int i=n;i;i--)bl[blk[i]].lst=i-1;
}
void update(int u,int w)
{
	bl[blk[u]].update(pos[u],w);
	for(int i=blk[u];i;i--)merge(bl[i].suf[1],ans[i+1],bl[i].val,ans[i]);
}
int query(int k)
{
	int res=0x3f3f3f3f;qu q;
	for(int i=1;i<=blk[n];i++)res=min(res,bl[i].query(k,res));
	for(int i=blk[n],w,tmp;i>=2;i--)
	{
		w=bl[i-1].val;q=bl[i-1].pre[bl[i-1].sz];
		for(int j=1,k=q.sz,r=0;j<=ans[i].sz;j++)
		{
			if((ans[i][j]>>5)-bl[i].lst>=res)break;
			r|=(1<<(ans[i][j]&31));if((r|w)<k)continue;
			while(k!=1)
			{
				tmp=w&(~(1<<(q[k]&31)));
				if((r|tmp)<k)break;k--;w=tmp;
			}
			res=min(res,(ans[i][j]>>5)-(q[k]>>5)+1);
			if(k==1)break;
		}
	}
	if(res==0x3f3f3f3f)return -1;
	return res;
}
int main()
{
	cin>>n>>m;init();
	for(int i=1;i<=n;i++)cin>>bl[blk[i]][pos[i]];
	for(int i=1;i<=blk[n];i++)bl[i].build();
	for(int i=blk[n];i;i--)merge(bl[i].suf[1],ans[i+1],bl[i].val,ans[i]);
	for(int i=1,op,k,x;i<=m;i++)
	{
		cin>>op>>k;
		if(op==1){cin>>x;update(k,x);}
		else cout<<query(k)<<'\n';
	}
}
2025/1/10 20:10
加载中...