• luogu CF901C Bipartite Segments |Tarjan+二分


    题意翻译

    给你一个有nnn个点的无向图,没有偶环。我们把节点标记为1..n1..n1..n。

    你需要回答qqq个询问,每一个询问由一个区间L,R组成,你需要计算出有多少个点对x,y,满足由[x,y]之间的所有点组成的子图是一个二分图。

    输入数据第一行两个整数 n,mn,mn,m (1≤n≤3×105,1≤m≤3×1051le nle 3 imes 10^5,1le mle 3 imes10^51≤n≤3×105,1≤m≤3×105)代表点数和边数 接下来的mmm行,每行两个整数,表示一条无向边,保证无自环,保证无重边

    一个整数 q(1≤q≤3×105)q(1le qle3 imes 10^5)q(1≤q≤3×105),表示询问个数

    接下来qqq行,每行一个询问[L,R]

    对于每个询问,输出一个整数,表示满足条件的点对[x,y]的个数


    设一个cnt[i]表示i往左最多可以扩展到哪个下标

    可以发现cnt必然是 不下降 的序列

    对于询问[x,y]中的一个点i,若cnt[i]>=x 则答案贡献为 i-cnt[i]+1

    若cnt[i]<x则答案贡献为i-x+1,

    而cnt是递增的,我们只需要二分找到分界点x的下标 O(logn)

    对于第一种情况,我们可以前缀和求 O(1)

    对于第二种情况,我们可以等差数列求和 O(1)

    怎么预处理cnt[i]呢?

    先用Tarjan求出一个环内最小编号最大编号,然后这个环的最大编号的cnt[i]等于最小编号

    其它情况的cnt可以直接递推

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define ll long long
    void qmax(int &x, int y){
        if (x < y)x = y;
    }
    void qmin(int &x, int y){
        if (x > y)x = y;
    }
    const int _=6e5+10;
    int nxt[_<<1],head[_],go[_<<1],tot;
    inline void add(int u,int v){
        nxt[++tot]=head[u];head[u]=tot;go[tot]=v;
        nxt[++tot]=head[v];head[v]=tot;go[tot]=u;
    }
    int st[_],top;
    int vis[_],loop[_];
    int n,m,cnt[_],sum[_];
    void dfs(int x,int fa){
        vis[x]=1;
        st[++top]=x;
        for (int i=head[x];i;i=nxt[i])
        if (go[i]!=fa && !loop[go[i]]){
            if (!vis[go[i]]) dfs(go[i],x);
            else{
                int mx=0,mn=n+1;
                for (int j=top,y;;j--)
                {
                    y=st[j];
                    qmax(mx,y);
                    qmin(mn,y);
                    loop[y]=1;
                    if (st[j]==go[i]) break;
                }
                if (!cnt[mx]) cnt[mx]=mn;
                else qmax(cnt[mx],mn);
            }
        }
        --top;
    }
    signed main(){   
        cin>>n>>m;
        for(int i=1,u,v;i<=m;i++){
            scanf("%lld%lld",&u,&v);
            add(u,v);
        }
        for(int i=1;i<=n;i++)
            if(!vis[i])dfs(i,i);
        cnt[0]=0;
        for(int i=1;i<=n;i++){
            qmax(cnt[i],cnt[i-1]);
            sum[i]=sum[i-1]+cnt[i];
        }
        int q,x,y,ans,mid; cin>>q;
        while (q--){
            scanf("%lld%lld",&x,&y);
            int l=x,r=y,s=y+1;
            while (l<=r){
                mid=(l+r)>>1;
                if (cnt[mid]>=x)
                    r=mid-1,s=mid;
                else l=mid+1;
            }
            ans=(ll)(y+x)*(y-x+1)/2-(sum[y]-sum[s-1])-(ll)(x-1)*(s-x);
            printf("%lld
    ",ans);
        }
    }
    
  • 相关阅读:
    PHP下载/采集远程图片到本地
    【问底】徐汉彬:PHP7和HHVM的性能之争
    IntelliJ IDEA 14.x 创建工作空间与多个Java Web项目
    IntelliJ IDEA 14.x 与 Tomcat 集成,创建并运行Java Web项目
    启动MongoDB时,提示:error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
    IntelliJ IDEA 14.x 的 project 和 module 是啥关系?
    Intellij IDEA 14.x 菜单项中Compile、Make和Build的区别
    Github上的PHP资源汇总大全
    Intellij IDEA 14.x 中的Facets和Artifacts的区别
    Spring技术内幕:Spring AOP的实现原理(二)
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12194440.html
Copyright © 2020-2023  润新知