【BZOJ】5218: [Lydsy2017省隊十連測]友好城市 kosaraju+bitset+莫隊
阿新 • • 發佈:2018-12-11
題解
+莫隊+壓位+減枝 時間複雜度
程式碼
#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;
}