1. 程式人生 > >【BZOJ】5218: [Lydsy2017省隊十連測]友好城市 kosaraju+bitset+莫隊

【BZOJ】5218: [Lydsy2017省隊十連測]友好城市 kosaraju+bitset+莫隊

題解

kosarajukosaraju+莫隊+壓位+減枝 時間複雜度O(q(n+n232))O(q(\sqrt n + \dfrac{n^2}{32}))

程式碼

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<ctime>
#include
<vector>
#include<map> #include<cctype> #define RI register #define gc getchar() #define si isdigit(ch) #define ui unsigned int #define buic(x) __builtin_ctz((x)) using namespace std; const int N=155,M=3e5+10,MX=5e4+10; int n,m,q,sum,num; int block,in[M],ans[M]; int stk[N],top,df[N]
,dfn; int bel[N],mp[N][N]; struct Q{int l,r,id;}qr[MX]; struct L{int u,v;}le[M]; struct BI{ ui a[5]; inline void itia(){memset(a,0,sizeof(a));} inline void st(int pos){a[pos>>5]|=(1<<(pos&31));} inline void flip(int pos){a[pos>>5]^=(1<<(pos&31));} inline bool exi
(int pos){return (a[pos>>5]>>(pos&31))&1;} }g[N],rvg[N],vis; inline bool cmp(const Q&A,const Q&B){ return in[A.l]==in[B.l]?A.r<B.r:A.l<B.l; } char ch; inline void rd(int &x) { ch=gc;x=0; for(;!si;ch=gc); for(;si;ch=gc) x=x*10+(ch^48); } inline void init() { RI int i,j,k,t; rd(n);rd(m);rd(q); for(i=1;i<=m;++i){ rd(le[i].u),rd(le[i].v); le[i].u--;le[i].v--; } for(i=1;i<=q;++i) rd(qr[i].l),rd(qr[i].r),qr[i].id=i; block=sqrt(m)+1; for(i=1;i<=m;++i) in[i]=(i-1)/block+1; sort(qr+1,qr+q+1,cmp); } void dfs(int x) { vis.st(x);ui res; for(RI int i=0;i<5;++i) for(;;){ res=g[x].a[i]-(g[x].a[i] & vis.a[i]); if(!res) break; dfs(i<<5|buic(res)); } df[++dfn]=x; } void dfss(int x) { vis.st(x);ui res;int qw;num++; for(RI int i=0;i<5;++i) for(;;){ res=rvg[x].a[i]-(rvg[x].a[i]&vis.a[i]); if(!res) break; qw=i<<5|buic(res); bel[qw]=bel[x]; dfss(qw); } } inline void upp(int pos) { sum=dfn=0; RI int i; vis.itia(); for(i=n;i<160;++i) vis.st(i); for(i=0;i<n;++i) if(!vis.exi(i)) dfs(i); vis.itia(); for(i=n;i<160;++i) vis.st(i); for(i=dfn;i;--i) if(!vis.exi(df[i])){ num=0;bel[df[i]]=df[i]; dfss(df[i]);sum+=(num-1)*num/2; } ans[pos]=sum; } void Mo() { RI int um,i,j,cg,x,y;int l,r,L,R; l=qr[1].l;r=qr[1].r; for(i=l;i<=r;++i){ x=le[i].u;y=le[i].v; mp[x][y]++; if(mp[x][y]==1) g[x].st(y),rvg[y].st(x); } upp(qr[1].id); for(um=2;um<=q;++um){ cg=0;L=qr[um].l;R=qr[um].r; if(L<l){ for(i=L;i<l;++i){ x=le[i].u;y=le[i].v; mp[x][y]++; if(mp[x][y]==1){ g[x].st(y);rvg[y].st(x); if(!cg && bel[x]!=bel[y]) cg=1; } } l=L; } if(R>r){ for(i=r+1;i<=R;++i){ x=le[i].u;y=le[i].v; mp[x][y]++; if(mp[x][y]==1){ g[x].st(y);rvg[y].st(x); if(!cg && bel[x]!=bel[y]) cg=1; } } r=R; } if(l<L){ for(i=l;i<L;++i){ x=le[i].u;y=le[i].v; mp[x][y]--; if(mp[x][y]==0){ g[x].flip(y);rvg[y].flip(x); if((!cg) && bel[x]==bel[y]) cg=1; } } l=L; } if(r>R){ for(i=R+1;i<=r;++i){ x=le[i].u;y=le[i].v; mp[x][y]--; if(mp[x][y]==0){ g[x].flip(y);rvg[y].flip(x); if((!cg) && bel[x]==bel[y]) cg=1; } } r=R; } if(cg) upp(qr[um].id); else ans[qr[um].id]=sum; } for(i=1;i<=q;++i) printf("%d\n",ans[i]); } int main(){ init(); Mo(); return 0; }