题意:
n个原子,初始有m条化学键,q次操作,每次加或删一条化学键,或询问当前有多少分子。 在变化过程中始终保持着一种特殊的性质:不存在这样的原子序列 a1,a2,…,an(n>3)满足 a1 与 a2、a2 与a3、……、an-1 与 an 以及 an 与 a1 都通过化学键相连,但它们之间却没有其他化学键相连的情况。
n≤5000,m≤200000,q≤10000
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<set>
#define PII pair<int,int>
#define N 5100
#define M 210000
#define lb lower_bound
#define mp make_pair
using namespace std;
struct node{int o,x,y;}q[M];
struct node1{int pre,nex,x,y;}a[M];
set<PII> s;
set<PII>::iterator it;
int n,m,fa[N],ans,cnt,ql,num,las,f[N];
int find(int x)
{
if(x!=fa[x]) fa[x]=find(fa[x]);
return fa[x];
}
void merge(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx==fy) return;
ans--;
fa[fx]=fy;
}
void del(int k)
{
a[a[k].nex].pre=a[k].pre;
a[a[k].pre].nex=a[k].nex;
}
void make()
{
for(int i=1;i<=n;i++) fa[i]=f[i];
ans=cnt;
for(int i=0;i<=las;i=a[i].nex) merge(a[i].x,a[i].y);
printf("%d\n",ans);
}
void solve()
{
for(int i=1;i<=ql;i++)
{
if(q[i].o==0) make();
else if(q[i].o==1) las++;
else
for(int j=0;j<=las;j=a[j].nex)
if(a[j].x==q[i].x && a[j].y==q[i].y) {del(j);break;}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
if(x>y) swap(x,y);
s.insert(mp(x,y));
}
scanf("%d",&ql);
for(int i=1;i<=ql;i++)
{
char c;scanf("%c",&c);while(c!='Q' && c!='A' && c!='D') scanf("%c",&c);
if(c=='A' || c=='D')
{
if(c=='A') q[i].o=1;
else q[i].o=-1;
scanf("%d%d",&q[i].x,&q[i].y);
if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
if(c=='D')
{
it=s.lb(mp(q[i].x,q[i].y));
if(it==s.end()) continue;
if((*it)==mp(q[i].x,q[i].y))
{
s.erase(it);
a[++num].x=q[i].x;a[num].y=q[i].y;
a[num].pre=num-1;a[num].nex=num+1;
}
}
}
}
las=num;
for(int i=1;i<=ql;i++)
if(q[i].o==1)
{
a[++num].x=q[i].x;a[num].y=q[i].y;
a[num].pre=num-1;a[num].nex=num+1;
}
a[0].nex=1;
for(int i=1;i<=n;i++) fa[i]=i;
ans=n;
for(it=s.begin();it!=s.end();it++)
{
int x=(*it).first,y=(*it).second;
merge(x,y);
}
cnt=ans;
for(int i=1;i<=n;i++) f[i]=fa[i];
solve();
return 0;
}
题解:
我看了题解!感觉被侮辱了T_T。。记录一下这愉♂快的时刻
注意所有的环都是若干三元环组成的,那么。。有什么卵用?!
q很小,那么初始m条边中受影响的最多只有q条,将不受影响的边缩起来,剩下的暴力。最多只有O(q)条边,加入暴力加,删除暴力删,询问暴力问。。复杂度O(nq+q*q)