zoukankan      html  css  js  c++  java
  • bzoj 5218: [Lydsy2017省队十连测]友好城市

    题意:


    这题显然直接tarjan是做不了的。

    这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客

    于是结合莫队,我们有了个暴力。

    发现主要瓶颈是dfs过程中找最小的未经过的点,我们用bitset优化一下就过了。

    注意有重边,不能直接在biset中删除,要开个邻接矩阵判一下。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    typedef long long ll;
    const int maxn=200;
    const int maxm=3*1e5+10;
    const int maxq=50010;
    int n,m,Q,t,block,nowl=1,nowr,tot,cnt;
    int pos[maxm],size[maxn],a[maxn];
    int cnt1[maxn][maxn],cnt2[maxn][maxn];
    ll ans[maxq];
    struct Edge{int u,v;}E[maxm];
    struct Query{int l,r,id;}qr[maxq];
    bitset<maxn>vis;
    bitset<maxn>e1[maxn],e2[maxn];
    inline int read()
    {
    	re char c=getchar();re int res=0,f=1;
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    	return res*f;
    }
    char num[35];
    inline void write(ll x) 
    {
        if(!x){putchar('0');return;}
    	re ll tmp=x>0?x:-x;
        if(x<0)putchar('-');
        re int cnt=0;
        while(tmp>0) 
    	{
            num[cnt++]=tmp%10+'0';
            tmp/=10;
        }
        while(cnt>0)putchar(num[--cnt]);
    }
    inline bool cmp(Query x,Query y)
    {
    	if(pos[x.l]==pos[y.l])
    	{
    		if(pos[x.l]&1)return x.r<y.r;
    		else return x.r>y.r;
    	}
    	else return x.l<y.l;
    }
    inline void add(int id)
    {
    	re int x=E[id].u,y=E[id].v;
    	cnt1[x][y]++,cnt2[y][x]++;
    	if(cnt1[x][y]==1)e1[x].set(y);
    	if(cnt2[y][x]==1)e2[y].set(x);
    }
    inline void del(int id)
    {
    	re int x=E[id].u,y=E[id].v;
    	cnt1[x][y]--,cnt2[y][x]--;
    	if(!cnt1[x][y])e1[x].reset(y);
    	if(!cnt2[y][x])e2[y].reset(x);
    }
    void dfs1(int x)
    {
    	vis.reset(x);
    	bitset<maxn>now=vis&e1[x];
    	while(now.any())
    	{
    		dfs1(now._Find_first());
    		now&=vis;
    	}
    	a[++cnt]=x;
    }
    void dfs2(int x)
    { 
    	size[tot]++;vis.reset(x);
    	bitset<maxn>now=vis&e2[x];
    	while(now.any())
    	{
    		dfs2(now._Find_first());
    		now&=vis;
    	}
    }
    inline ll solve()
    {
    	memset(size,0,sizeof(size));
    	vis.set();cnt=tot=0;
    	re ll res=0;
    	for(re int i=1;i<=n;i++)if(vis.test(i))dfs1(i);
    	vis.set();
    	for(re int i=cnt;i;i--)if(vis.test(a[i]))tot++,dfs2(a[i]);
    	for(re int i=1;i<=tot;i++)res+=size[i]*(size[i]-1)/2;
    	return res;
    }
    int main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	n=read(),m=read(),Q=read();
    	for(re int i=1;i<=m;i++)E[i].u=read(),E[i].v=read();
    	for(re int i=1;i<=Q;i++)qr[i].l=read(),qr[i].r=read(),qr[i].id=i;
    	t=pow(m,1.0*3/5);
    	for(re int i=1;i<=m;i++)pos[i]=(i-1)/t+1;
    	sort(qr+1,qr+Q+1,cmp);
    	for(re int i=1;i<=Q;i++)
    	{
    		while(nowl<qr[i].l)del(nowl++);
    		while(nowl>qr[i].l)add(--nowl);
    		while(nowr<qr[i].r)add(++nowr);
    		while(nowr>qr[i].r)del(nowr--);
    		ans[qr[i].id]=solve();
    	}
    	for(re int i=1;i<=Q;i++,puts(""))write(ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    我败在了盲目和没有计划
    跟我一起学.NetCore目录
    跟我一起学.NetCore之依赖注入作用域和对象释放
    跟我一起学.NetCore之Asp.NetCore启动流程浅析
    std::unordered_map
    Android apps for “armeabi-v7a” and “x86” architecture: SoC vs. Processor vs. ABI
    android studio 配置相关问题
    shell script
    vscode配置
    linux常用命令笔记
  • 原文地址:https://www.cnblogs.com/nofind/p/12068074.html
Copyright © 2011-2022 走看看