• BZOJ3514: Codechef MARCH14 GERALD07加强版


    题解:  很久以前写的一道题 刚开始找不到切入点 我们这样考虑吧 对于每个查询 我们查询当前加入[l,r]边的联通快的个数 那么我们从联通块的本身出发 当前的联通块的个数应该等于n-关键路径的条数 关键路径等于总路径-无用路径的条数 那么我们怎么去判断一条路径是无用的呢 当且仅当 你加入这条边形成环的最小标号是无用路径 然后主席数维护区间无用路径的条数即可

    /**************************************************************
        Problem: 3514
        User: c20161007
        Language: C++
        Result: Accepted
        Time:37272 ms
        Memory:134500 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    const int MAXN=4e5+10;
    const int inf=1e9+10;
    using namespace std;
    ll readll(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int readint(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    int minn[MAXN],ch[MAXN][2],key[MAXN],pre[MAXN],res[MAXN],fa[MAXN],n,m,q,type,cnt;
    int root[MAXN];
    bool rt[MAXN];
    void Treavel(int x)
    {
        if(x)
        {
        //  cout<<x<<endl;
            Treavel(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d 最小值 %2d,key=%2d
    ",x,ch[x][0],ch[x][1],pre[x],minn[x],key[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug(int rp)
    {
        printf("root:%d
    ",rp);
        Treavel(rp);
    }
    void reverse(int r){
        if(!r) return ;
        swap(ch[r][0],ch[r][1]);
        res[r]^=1;
    }
    void push(int r){
        if(res[r]){
            reverse(ch[r][0]);
            reverse(ch[r][1]);
            res[r]^=1;
        }
    }
    void up(int r){
        if(!r) return ;
        minn[r]=r;
        if(key[minn[ch[r][0]]]<key[minn[r]]) minn[r]=minn[ch[r][0]];
        if(key[minn[ch[r][1]]]<key[minn[r]]) minn[r]=minn[ch[r][1]];
    }
    void P(int r){
        if(!rt[r]) P(pre[r]);
        push(r);
    }
    void rotate(int x,int kind){
        int y=pre[x];
        pre[ch[x][kind]]=y;ch[y][!kind]=ch[x][kind];
        if(rt[y]) rt[y]=0,rt[x]=1;
        else ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);
    }
    void splay(int x){
        P(x);
        while(!rt[x]){
            if(rt[pre[x]]) rotate(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x];int kind=ch[pre[y]][0]==y;
                if(ch[y][kind]==x) rotate(x,!kind),rotate(x,kind);
                else rotate(y,kind),rotate(x,kind);
            }
        }
        up(x);
    }
    void access(int x){
        int y=0;
        while(x){
            splay(x);
            if(ch[x][1]) rt[ch[x][1]]=1,pre[ch[x][1]]=x;
            ch[x][1]=y;
            up(x);
            if(y) rt[y]=0;
            y=x;x=pre[x];
        }
    }
    void mroot(int u){
        access(u);splay(u);
        reverse(u);
    }
    bool pd(int u,int v){
        while(pre[u]) u=pre[u];
        while(pre[v]) v=pre[v];
        return u==v;
    }
    void Link(int u,int v){
        mroot(u);pre[u]=v;
    }
    void destory(int u,int v){
        mroot(u);access(v);splay(v);
        rt[u]=rt[v]=1;pre[u]=pre[v]=0;ch[v][0]=0;
        up(v);up(u);
    }
    int querty(int u,int v){
        mroot(u);access(v);splay(v);
    //  debug(v);
        //cout<<u<<" "<<v<<" "<<minn[v]<<endl;
        return minn[v];
    }
    void newnode(int t){
        rt[t]=1;res[t]=pre[t]=ch[t][0]=ch[t][1]=0;minn[t]=t;key[t]=inf;
    }
    pii w[MAXN];
    typedef struct node{
        int l,r,sum;
    }node;
    node d[25*MAXN];
    void update(int &x,int y,int l,int r,int t){
        cnt++;x=cnt;d[x]=d[y];d[x].sum--;
        //cout<<l<<" "<<r<<" "<<t<<" "<<d[x].sum<<endl;
        if(l==r) return ;
        int mid=(l+r)>>1;
        if(t<=mid) update(d[x].l,d[y].l,l,mid,t);
        else update(d[x].r,d[y].r,mid+1,r,t);
    }
    int ans;
    void querty1(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            //cout<<l<<" "<<r<<" "<<d[x].sum<<endl;
            ans+=d[x].sum;
            return ;
        }
        int mid=(l+r)>>1;
        if(ql<=mid) querty1(d[x].l,l,mid,ql,qr);
        if(qr>mid) querty1(d[x].r,mid+1,r,ql,qr);
    }
    int main(){
        ios::sync_with_stdio(false);
        n=readint();m=readint();q=readint();type=readint();
        key[0]=inf;cnt=0;
        for(int i=1;i<=n+m;i++) newnode(i);
        int u,v;
        for(int i=1;i<=m;i++){
            u=readint();v=readint();w[i].first=u;w[i].second=v;
            if(u==v){
                fa[i]=i;continue;
            }
            //cout<<pd(u,v)<<endl;
            if(!pd(u,v)){
                fa[i]=0;key[i+n]=i;Link(u,i+n);Link(v,i+n);
                //cout<<i<<" "<<key[i+n]<<endl;
            }
            else{
                int t=querty(u,v);int tt=key[t];
                //cout<<t<<" "<<tt<<endl;
                fa[i]=tt;
                destory(t,w[tt].first);destory(t,w[tt].second);
                key[i+n]=i;
                Link(i+n,u);Link(i+n,v);
            }
        }
        //cout<<"sb"<<endl;
    //  for(int i=1;i<=m;i++) cout<<fa[i]<<" ";
    //  cout<<endl;
        for(int i=1;i<=m;i++){
            if(!fa[i]){
                root[i]=root[i-1];continue;
            }
            //cout<<"sb"<<endl;
            update(root[i],root[i-1],1,m,fa[i]);
            //cout<<"sb"<<endl;
        }
        int Lans=0;int l,r;
        for(int i=1;i<=q;i++){
            l=readint();r=readint();
            if(type==1) l^=Lans,r^=Lans;
            if(l>r) swap(l,r);
            ans=0;querty1(root[r],1,m,l,r);
            //cout<<ans<<endl;
            Lans=n-((r-l+1)+ans);
            printf("%d
    ",Lans);
        }
        return 0;
    }
    

    3514: Codechef MARCH14 GERALD07加强版

    Time Limit: 60 Sec  Memory Limit: 256 MB
    Submit: 2363  Solved: 907
    [Submit][Status][Discuss]

    Description

    N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

    Input

    第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
    接下来M行,代表图中的每条边。
    接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。

    Output

     K行每行一个整数代表该组询问的联通块个数。

    Sample Input

    3 5 4 0
    1 3
    1 2
    2 1
    3 2
    2 2
    2 3
    1 5
    5 5
    1 2

    Sample Output

    2
    1
    3
    1

    HINT

    对于100%的数据,1≤N、M、K≤200,000。


    2016.2.26提高时限至60s

    Source

  • 相关阅读:
    ECharts grid组件离容器的距离
    防火墙centos7执行 service iptables status报错问题完美解决
    linux 在切换用户时出现:命令提示符-bash-4.1$错误解决
    DataTable转为TXT文档
    读取ecxel中数据——NPOI.Excel和Aspose
    SQL连接数据库
    fiddler软件无法生成代码
    webapi发布后更新(无前台时)
    webapi日志记录(TXT存储)
    webapi使用Get进行访问时,url长度被限制解决办法
  • 原文地址:https://www.cnblogs.com/wang9897/p/9498646.html
Copyright © 2020-2023  润新知