随机赋点权值,sum表示所有点的点权乘该点的入度,若与所有点权之和相同,则可以反击。
正确性未知,好像没问题,但样例不能过。
代码如下
#include<bits/stdc++.h>
using namespace std;
long long n,m,u,v,q,opt[500001],sum,ans,a[500001],b[500001],f[500001],val[500001],r[500001],T=50;
bool fnl[500001];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v;
f[v]++;
}
cin>>q;
for(int i=1;i<=q;i++){
cin>>opt[i];
if(opt[i]==1||opt[i]==3)cin>>a[i]>>b[i];
else cin>>a[i];
}
while(T--){
sum=0,ans=0;
for(int i=1;i<=n;i++){
val[i]=rand()*rand();
r[i]=val[i]*f[i];
sum+=r[i];
ans+=val[i];
}
for(int i=1;i<=q;i++){
if(opt[i]==1)r[b[i]]-=val[b[i]],sum-=val[b[i]];
else if(opt[i]==2)sum-=r[a[i]],r[a[i]]=0;
else if(opt[i]==3)r[b[i]]+=val[b[i]],sum+=val[b[i]];
else sum+=f[a[i]]*val[a[i]]-r[a[i]],r[a[i]]=f[a[i]]*val[a[i]];
if(sum!=ans)fnl[i]=1;
}
}
for(int i=1;i<=q;i++){
if(fnl[i])cout<<"NO\n";
else cout<<"YES\n";
}
}
若思路正确,请求修改
若思路错误,请求指出