【BZOJ3562】【SHOI2014】神奇化合物 特技

来源:互联网 发布:高三自学数学知乎 编辑:程序博客网 时间:2024/05/02 03:06

广告:

#include <stdio.h>int main(){    puts("转载请注明出处[vmurder]谢谢");    puts("网址:blog.csdn.net/vmurder/article/details/44016219");}

题解:

一开始让我写这道题,其实我是,是拒绝的。
我跟大爷讲,我拒绝,因为,其实我,根本搞不懂这个时间复杂度。
大爷跟我讲,敲时加特技,代码很短很快很好。
加了30行特技之后呢,代码DUANG~~~
后来我其实知道这个是真的,是有时间复杂度保证的。我的代码呢,就这么加特技,加了很多特技,代码,DUANG~~DUANG~~DUANG。
我敲完的代码就是这个样子的,你敲完也会是这个样子,因为,加,特技。

特技:

离线后有些边一定不会被删,然后用这些边来并查集缩点。
然后数据规模就很小的,这样我们就可以暴力搞了。

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 5050#define M 501000using namespace std;int ru[M],rv[M];struct KSD{    int v,len,next;}e[M];int head[N],cnt;int f[N],map[N][N];int find(int x){return (x==f[x])?x:f[x]=find(f[x]);}inline void add(int u,int v,int len=1){    map[u][v]=++cnt;    e[cnt].v=v;    e[cnt].len=len;    e[cnt].next=head[u];    head[u]=cnt;}int n,m,q;struct QUERY{    int f,a,b;    QUERY(int _f=0,int _a=0,int _b=0):f(_f),a(_a),b(_b){}    void read(int _f)    {        f=_f;        scanf("%d%d",&a,&b);        if(f==2)map[a][b]=map[b][a]=0;    }}query[10100];bool vis[N];void dfs(int x){    int i,v;    vis[x]=true;    for(i=head[x];i;i=e[i].next)    {        if(e[i].len)        {            v=e[i].v;            if(!vis[v])dfs(v);        }    }}char tt[5];int main(){    freopen("test.in","r",stdin);     int i,j,k;    int a,b,c;    int fa,fb;    scanf("%d%d",&n,&m);    for(i=1;i<=n;i++)f[i]=i;    for(i=1;i<=m;i++)    {        scanf("%d%d",&a,&b);        ru[i]=a,rv[i]=b;        map[a][b]=map[b][a]=true;    }    scanf("%d",&q);    for(i=1;i<=q;i++)    {        scanf("%s",tt);        if(tt[0]=='Q')continue;        else if(tt[0]=='A')query[i].read(1);        else query[i].read(2);    }    for(i=1;i<n;i++)for(j=i+1;j<=n;j++)        if(map[i][j])f[find(j)]=find(i);    memset(map,0,sizeof map),cnt=1;    for(i=1;i<=m;i++)    {        a=find(ru[i]),b=find(rv[i]);        if(a==b)continue;        if(map[a][b])e[map[a][b]].len++,e[map[b][a]].len++;        else add(a,b),add(b,a);    }    for(i=1;i<=n;i++)find(i);    for(i=1;i<=q;i++)    {        if(!query[i].f)        {            int ret=0;            memset(vis,0,sizeof vis);            for(j=1;j<=n;j++)if(f[j]==j&&!vis[j])            {                ret++;                dfs(j);            }            printf("%d\n",ret);        }        else if(query[i].f==1)        {            a=f[query[i].a],b=f[query[i].b];            if(map[a][b])e[map[a][b]].len++,e[map[b][a]].len++;            else add(a,b),add(b,a);        }        else         {            a=f[query[i].a],b=f[query[i].b];            e[map[a][b]].len--,e[map[b][a]].len--;        }    }    return 0;}
1 0