zoukankan      html  css  js  c++  java
  • bzoj3514 Codechef MARCH14 GERALD07加强版

    有些纪念意义的题

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

    $N,M,Q leq 200000$

    受某远古$CF$题的影响,大力$LCT$硬搞

    一个神奇的做法:

    令每条边边权为加入时间

    搞一个数组$used$,加边的时候如果形成了环,则弹掉边权最小的那条边,并记录$used[i]=j$表示$i$弹掉了$j$

    特别地,当i上有一个自环时$used[i]=i$,不弹掉的话$used[i]=0$

    这样的话每个询问的答案就是$n-[l,r]$区间上$used$值小于$l$的边的数量

    正确性:

    如果一条边的$used$值不小于$l$,说明它能跟$[l,r]$上的边连成一个环,对答案没有贡献

    如果小于$l$,说明是一条新边,对答案的贡献为$-1$

    于是开个树套树/主席树记一下$[l,r]$区间上小于$k$的数的个数就好啦

    /**************************************************************
        Problem: 3514
        User: Ez3real
        Language: C++
        Result: Accepted
        Time:30504 ms
        Memory:79436 kb
    ****************************************************************/
     
    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch;
        for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f=-f;
        for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
        return x*f;
    }
    const int maxn = 400010 , inf = 1e9;
    int n,m,q,type,lastans;
    namespace LCT
    {
        int son[maxn][2],fa[maxn],rev[maxn];
        int mn[maxn],val[maxn];
        int st[maxn],top;
         
        #define lc son[x][0]
        #define rc son[x][1]
        inline int isroot(int x){return (son[fa[x]][0] != x) && (son[fa[x]][1] != x);}
        inline void pushup(int x)
        {
            mn[x] = x;
            if(val[mn[lc]] < val[mn[x]]) mn[x] = mn[lc];
            if(val[mn[rc]] < val[mn[x]]) mn[x] = mn[rc];
        }
        inline void pushdown(int x)
        {
            if(rev[x])
            {
                rev[x] ^= 1; 
                rev[lc] ^= 1;
                rev[rc] ^= 1;
                swap(lc,rc);
            }
        }
        inline void rotate(int x)
        {
            int y=fa[x],z=fa[y];
            int l=(son[y][1] == x),r = l ^ 1;
            if(!isroot(y))son[z][son[z][1] == y] = x;
            fa[x] = z,fa[y] = x, fa[son[x][r]] = y;
            son[y][l] = son[x][r] , son[x][r] = y ;
            pushup(y),pushup(x);
        }
        inline void splay(int x)
        {
            st[top=1]=x;
            for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i];
            for(int i=top;i;i--)pushdown(st[i]);
            while(!isroot(x))
            {
                int y=fa[x],z=fa[y];
                if(!isroot(y))
                {
                    if(son[y][0] == x ^ son[z][0] == y)rotate(x);
                    else rotate(y);
                }
                rotate(x);
            }
        }
        inline void access(int x)
        {
            for(int y=0;x;y=x,x=fa[x])splay(x),son[x][1] = y,pushup(x);
        }
        inline void makert(int x)
        {
            access(x),splay(x),rev[x]^=1;
        }
        inline void link(int x,int y)
        {
            makert(x),fa[x]=y;
        }
        inline void split(int x,int y)
        {
            makert(x),access(y),splay(y);
        }
        inline void cut(int x,int y)
        {
            split(x,y);
            son[y][0]=fa[x]=0;
        }
        inline int find(int x)
        {
            access(x),splay(x);
            while(son[x][0]) x = son[x][0];
            return x;
        }
        inline int LCquery(int x,int y)
        {
            split(x,y);
            return mn[y];
        }
    }
     
    namespace HujinTree
    {
        int SIZE;
        const int MAXNODE = 4000010;
        int root[MAXNODE];
        int ls[MAXNODE],rs[MAXNODE],nval[MAXNODE];
        inline void insert(int &cur,int l,int r,int pre,int va)
        {
            cur = ++SIZE;
            nval[cur] = nval[pre] + 1;
            if(l == r)return;
            ls[cur] = ls[pre] , rs[cur] = rs[pre];
            int mid = (l+r) >> 1;
            if(va <= mid) insert(ls[cur],l,mid,ls[pre],va);
            else insert(rs[cur],mid+1,r,rs[pre],va);
        }
        inline int query(int cur,int l,int r,int pre,int va)
        {
            if(r == va)return nval[cur] - nval[pre];
            int mid = (l+r) >> 1;
            if(va <= mid)return query(ls[cur],l,mid,ls[pre],va);
            else return nval[ls[cur]] - nval[ls[pre]] + query(rs[cur],mid+1,r,rs[pre],va);
        }
    }
     
    namespace LCGraph
    {
        using namespace HujinTree;
        using namespace LCT;
        struct EDG{int u,v;}es[maxn];
        int used[maxn];
        inline int main()
        {
            n=read(),m=read(),q=read(),type=read();
            val[0] = inf;
            for(int i=1;i<=n;i++)mn[i] = i, val[i] = inf;
            for(int i=1;i<=m;i++)es[i].u=read(),es[i].v=read();
            //return 0;
            int temp = n;
            for(int i=1;i<=m;i++)
            {
                int uu = es[i].u, vv = es[i].v;
                if(uu == vv){used[i] = i;continue;}
                if(find(uu) == find(vv))
                {
                    int a = LCquery(uu,vv);
                    int av = val[a];
                    used[i] = av;
                    //return 0;
                    cut(uu,a),cut(vv,a);
                }
                mn[++temp] = temp;val[temp] = i;
                link(uu,temp) ,link(vv,temp);
            }
            for(int i=1;i<=m;i++)
                insert(root[i],0,m,root[i-1],used[i]);
            //return 0;
            while(q--)
            {
                int l,r;
                l=read(),r=read();
                if(type == 1)l ^= lastans, r ^= lastans;
                lastans = n - query(root[r],0,m,root[l-1],l-1);
                //lastans = query(root[r],0,m,root[l-1],l-1);
                printf("%d
    ",lastans);
            }
        }
    }
     
    int main()
    {
        LCGraph::main();
        return 0;
    }
    View Code

    人傻常数大,一开始60s过不了第一个点QAQ

  • 相关阅读:
    使用java.util.Properties类读写配置文件
    maven配置文件setting.xml字段注释
    使用Nexus搭建Maven代理仓库
    Memcached 内存管理详解
    Memcached常用命令及使用说明
    使用NTP协议服务器时间同步
    Eclipse打JAR包的使用
    Eclipse插件的各种安装方法
    Java中代理对象的使用小结
    tp5框架成功、失败提示模板修改
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/8459879.html
Copyright © 2011-2022 走看看