社区讨论

求调

P5065[Ynoi Easy Round 2014] 不归之人与望眼欲穿的人们参与者 25已保存回复 26

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
26 条
当前快照
1 份
快照标识符
@mm0dan8z
此快照首次捕获于
2026/02/24 16:52
2 周前
此快照最后确认于
2026/02/26 09:40
上周
查看原帖
三个点 RE,死活调不出来。问了 AI,AI 也调不出来。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5,b=224,M=N/b+5;
struct sgt{
	#define mid ((le+ri)>>1)
	#define ls (u<<1)
	#define rs ((u<<1)|1)
	#define lp ls,le,mid
	#define rp rs,mid+1,ri
	int s[N<<2];
	void push_up(int u){
		s[u]=s[ls]|s[rs];
	}
	void init(int u,int le,int ri,int a[]){
		if(le==ri){
			s[u]=a[le];
			return;
		}
		init(lp,a);
		init(rp,a);
		push_up(u);
	}
	int gets(int u,int le,int ri,int x,int y,int k){
		if(x<=le&&ri<=y){
			if((k|s[u])==k){
				return -1;
			}
		}
		if(le==ri){
			return le;
		}
		if(x<=mid){
			int w=gets(lp,x,y,k);
			if(w!=-1) return w;
		}
		if(y>mid){
			int w=gets(rp,x,y,k);
			if(w!=-1) return w;
		}
		return -1;
	}
	#undef mid
}t;
struct ds{
	deque<int> s;
	vector<int> l,r;
	void rebuild(){
		int mid=s.size()/2;
		for(int i=mid;i>=0;i++){
			int w=s[i];
			if(!l.empty()) w|=l.back();
			l.push_back(w);
		}
		for(int i=mid+1;i<(int)s.size();i++){
			int w=s[i];
			if(!r.empty()) w|=r.back();
			r.push_back(w);
		}
	}
	void push_left(int x){
		s.push_front(x);
		int w=x;
		if(!l.empty()) w|=l.back();
		l.push_back(w);
	}
	void pop_right(){
		if(s.size()==1){
			s.clear(),l.clear(),r.clear();
			return;
		}
		if(r.empty()){
			rebuild();
		}
		s.pop_back();
		r.pop_back();
	}
	int que(){
		int w=0;
		if(!l.empty()) w|=l.back();
		if(!r.empty()) w|=r.back();
		return w;
	}
}r;
int n,q,a[N],blc;
vector<pair<int,int>> c[M],d[M];
int s[M][b+5];
void recas_1(int x){
	int l=b*x,r=min(b*(x+1)-1,n-1);
	c[x].clear(),d[x].clear();
	int res=0;
	for(int i=l;i<=r;i++){
		if((res|a[i])!=res){
			res|=a[i];
			c[x].push_back({i,res});
		}
	}
	res=0;
	for(int i=r;i>=l;i--){
		if((res|a[i])!=res){
			res|=a[i];
			d[x].push_back({i,res});
		}
	}
	reverse(d[x].begin(),d[x].end());
}
void recas_2(int x){
	int l=b*x,r=min(b*(x+1)-1,n-1);
	memset(s[x],0,sizeof(s[x]));
	vector<pair<int,int>> old,now;
	for(int i=l;i<=r;i++){
		now.push_back({i,a[i]});
		int w=a[i];
		for(int l=(int)old.size()-1;l>=0;l--){
			auto [pos,val]=old[l];
			if((w|val)!=w){
				w|=val;
				now.push_back({pos,w});
			}
		}
		reverse(now.begin(),now.end());
		for(auto [pos,val]:now){
			int len=i-pos+1;
			s[x][len]=max(s[x][len],val);
		}
		old=now;
		now.clear();
	}
	for(int i=2;i<=b;i++){
		s[x][i]=max(s[x][i],s[x][i-1]);
	}
}
int get_ans(int k){
	int ans=1<<30;
	for(int i=0;i<=blc;i++){
		int le=1,ri=b,mid;
		while(le<ri){
			mid=(le+ri)>>1;
			if(s[i][mid]<k) le=mid+1;
			else ri=mid;
		}
		if(s[i][le]>=k) ans=min(ans,le);
	}
	int lb=blc,lt=c[blc].size()-1;
	r=ds();
	for(int i=blc-1;i>=0;i--){
		if(i<blc-1) r.push_left(s[i+1][b]);
		for(int j=(int)d[i].size()-1;j>=0;j--){
			auto [pos,val]=d[i][j];
			while(1){
				int brk=0;
				while(lt==-1){
					if(lb==i+1){
						brk=1;
						break;
					}
					lb--;
					r.pop_right();
					lt=c[lb].size()-1;
				}
				if(brk) break;
				int res=r.que()|val|c[lb][lt].second;
				if(res>=k){
					ans=min(ans,c[lb][lt].first-pos+1);
					lt--;
				}
				else break;
			}
		}
	}
	if(ans>1e9) return -1;
	return ans;
}
signed main(){
//	freopen("std.in","r",stdin);
//	freopen("std.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>q;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	blc=(n-1)/b;
	for(int i=0;i<=blc;i++){
		recas_1(i);
		recas_2(i);
	}
	while(q--){
		int op,x,k;
		cin>>op;
		if(op==1){
			cin>>x>>k;
			x--;
			a[x]=k;
			recas_1(x/b);
			recas_2(x/b);
		}
		if(op==2){
			cin>>k;
			if(k==0){
				cout<<"0\n";
				continue;
			}
			cout<<get_ans(k)<<"\n";
		}
	}
}

回复

26 条回复,欢迎继续交流。

正在加载回复...