社区讨论

追忆失败

P11831[省选联考 2025] 追忆参与者 7已保存回复 9

讨论操作

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

当前回复
9 条
当前快照
1 份
快照标识符
@mlgxvitk
此快照首次捕获于
2026/02/11 02:33
上周
此快照最后确认于
2026/02/11 02:33
上周
查看原帖
O(n2w+n53)O(\frac{n^2}{w}+n^{\frac{5}{3}}) 做法。
AC #6 #11 #12 几乎都是在上万次询问后出错,调了一下午了,力竭了。
CPP
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define PLI pair<ll,int>
#define PIL pair<int,ll>
#define PLL pair<ll,ll>
#define fi first
#define se second
#define YES() cout<<"YES\n",0
#define NO() cout<<"NO\n",0
#define Yes() cout<<"Yes\n",0
#define No() cout<<"No\n",0
using ll=long long;
using uint=unsigned int;
using ull=unsigned long long;
using lb=long double;
const int N=1e5+5,M=52;
int c,T;
int n,m,q,a[N],b[N],pos[N];
int opt[N],l[N],r[N],x[N];
int tans[N][M];
bool vis[N];
int BL,BN,inb[N],L[N],R[N];
vector<int>e[N],bevis;
bitset<N>to[N];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin>>c>>T;
	while(T--){
		cin>>n>>m>>q;
		for(int i=1;i<=n;i++)	e[i].clear(),to[i].reset(),to[i][i]=1;
		for(int i=1,u,v;i<=m;i++)	cin>>u>>v,e[v].push_back(u);
		for(int i=n;i>=1;i--){
			for(auto it:e[i])	to[it]|=to[i];
		}
		BL=cbrt(1ll*n*n);BN=0;
		for(int i=1;i<=n;i+=BL){
			BN++;L[BN]=i,R[BN]=min(i+BL-1,n);
			for(int j=i;j<=min(i+BL-1,n);j++)	inb[j]=BN;
		}
		for(int i=1;i<=n;i++)	cin>>a[i],pos[a[i]]=i;
		for(int i=1;i<=n;i++)	cin>>b[i];
		for(int i=1;i<=q;i++){
			cin>>opt[i];
			if(opt[i]==3)	cin>>x[i]>>l[i]>>r[i];
			else	cin>>l[i]>>r[i];
		}
		for(int i=1;i<=q;i+=BL){
			int Ri=min(i+BL-1,q);bevis.clear();
			for(int j=i;j<=Ri;j++)	vis[l[j]]=vis[r[j]]=(opt[j]!=3);
			for(int j=1;j<=n;j++){
				for(int k=1;k<=BN;k++)	tans[j][k]=0;
				if(!vis[j])	tans[j][inb[a[j]]]=b[j];
				else	bevis.push_back(j);
			}
			for(int j=n;j>=1;j--){
				for(auto it:e[j]){
					for(int k=1;k<=BN;k++)	tans[it][k]=max(tans[it][k],tans[j][k]);
				}	
			}
			for(int j=i;j<=Ri;j++){
				if(opt[j]==1)	swap(pos[a[l[j]]],pos[a[r[j]]]),swap(a[l[j]],a[r[j]]);
				else if(opt[j]==2)	swap(b[l[j]],b[r[j]]);
				else{
					int ans=0;
					if(inb[l[j]]==inb[r[j]]){
						for(int k=l[j];k<=r[j];k++){
							if(to[x[j]][pos[k]])	ans=max(ans,b[pos[k]]);
						}
					}else{
						for(auto it:bevis){
							if(to[x[j]][it]&&l[j]<=a[it]&&a[it]<=r[j])	ans=max(ans,b[it]);
						}
						for(int k=l[j];k<=R[inb[l[j]]];k++){
							if(to[x[j]][pos[k]])	ans=max(ans,b[pos[k]]);
						}
						for(int k=L[inb[r[j]]];k<=r[j];k++){
							if(to[x[j]][pos[k]])	ans=max(ans,b[pos[k]]);
						}
						for(int k=inb[l[j]]+1;k<inb[r[j]];k++)	ans=max(ans,tans[x[j]][k]);
					}
					cout<<ans<<"\n";
				}
			}
			for(int j=i;j<=Ri;j++)	vis[l[j]]=vis[r[j]]=0;
		}
	}
}

回复

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

正在加载回复...