• bzoj 1095: [ZJOI2007]Hide 捉迷藏


    传送门

    传送中的动态点分治。

    就是在点分治的同时把分治树建立出来,然后每个节点用数据结构维护节点内的内容。

    这道题用了三个set,(貌似也可以用6个堆,每个set用一个ins堆和一个del堆来代替),一个维护当前rt的答案,就是当前点作为这一块联通块的根时往下能到达黑点的长度。一个维护当前rt对于它在分治树上的父亲的贡献,也就是当前rt里每一个点和当前rt在分治树上的父亲间的距离(用lca求)。再全局开一个set维护每个rt中可以算作答案的最大值和次大值的和。

    Achen不仅智力低下码力也这么低下。。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<set>
    const int N=100007,M=500007;
    typedef long long LL;
    using namespace std;
    int n,Q,clo[N];
    char o[10];
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1];
    void add(int u,int v) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
    }
    
    int f[N][17],R[N];
    int get_lca(int x,int y) {
        if(R[x]<R[y]) swap(x,y);
        int rs=0;
        for(int i=16;i>=0;i--) 
            if(R[f[x][i]]>=R[y]) {
                x=f[x][i];
                rs+=(1<<i); 
            }
        if(x==y) return rs;
        for(int i=16;i>=0;i--) 
            if(f[x][i]!=f[y][i]) {
                x=f[x][i]; y=f[y][i];
                rs+=(1<<(i+1));
            }
        return rs+2;
    }
    
    void dfs1(int x,int fa) {
        f[x][0]=fa;
        R[x]=R[fa]+1;
        for(int i=1;i<17;i++) f[x][i]=f[f[x][i-1]][i-1];
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
            dfs1(to[i],x);
        }
    } 
    
    int nowsz,nf[N],vis[N],rt,sz[N],mxson[N],g[N][2];
    void get_root(int x,int fa) {
        sz[x]=mxson[x]=1;
        for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]&&to[i]!=fa) {
            get_root(to[i],x);
            sz[x]+=sz[to[i]];
            mxson[x]=max(mxson[x],sz[to[i]]);
        }
        mxson[x]=max(mxson[x],nowsz-sz[x]);
        if(!rt||mxson[x]<mxson[rt]) rt=x;
    }
    
    struct node{
        int x,len;
        node(){}
        node(int x,int len):x(x),len(len){}
        friend bool operator <(const node &A,const node&B) {
            return A.len>B.len||(A.len==B.len&&A.x<B.x);
        } 
    }tpn,tpt;
    
    struct Node{
        int fi,se;
        Node(){}
        Node(int fi,int se):fi(fi),se(se){}
        friend bool operator <(const Node &A,const Node&B) {
            return A.fi+A.se>B.fi+B.se;
        } 
    }tpN;
    
    set<node>s[N];
    multiset<int>t[N];
    multiset<Node>mx;
    
    #define IT set<node>::iterator 
    #define It multiset<Node>::iterator
    int ec,F[N],nx[N],tt[N];
    void ADD(int u,int v) {
        nx[++ec]=F[u]; F[u]=ec; tt[ec]=v;
    }
     
    void calc(int x,int f) {
        int fi=-1,se=-1;
        for(int i=F[x];i;i=nx[i]) if(nf[tt[i]]==x) {
            if(!t[tt[i]].empty()) {
                int tlen=*t[tt[i]].rbegin();
                se=max(se,tlen);
                if(se>fi) swap(fi,se); 
            } 
        }
        if(!clo[x]) se=max(se,0); if(se>fi) swap(se,fi); 
        if(!f&&g[x][0]!=-1&&g[x][1]!=-1) 
            mx.erase(mx.find(Node(g[x][0],g[x][1]))); 
        g[x][0]=fi; g[x][1]=se;
        if(fi!=-1&&se!=-1) mx.insert(Node(fi,se)); 
    } 
    
    void get_devide(int x,int fa) {
        if(fa) ADD(fa,x);
        nf[x]=fa;
        vis[x]=1;
        for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
            rt=0; nowsz=sz[to[i]];
            get_root(to[i],0); int tprt=rt;
            get_devide(rt,x);
            for(IT it=s[tprt].begin();it!=s[tprt].end();it++) {
                tpn=*it;
                int dis=get_lca(tpn.x,x);
                t[tprt].insert(dis); 
                s[x].insert(node(tpn.x,dis));
            }
        }
        s[x].insert(node(x,0));
        calc(x,1); 
    } 
    
    void open(int y,int x,int len) {
        s[y].insert(node(x,len));
        if(nf[y]) t[y].insert(get_lca(x,nf[y])); 
        if(len>g[y][0]||len>g[y][1]) calc(y,0);
        if(nf[y]) open(nf[y],x,get_lca(nf[y],x));
    }
    
    void close(int y,int x,int len) {
        s[y].erase(node(x,len));
        if(nf[y]) t[y].erase(t[y].find(get_lca(x,nf[y])));
        if(len==g[y][0]||len==g[y][1]) calc(y,0); 
        if(nf[y]) close(nf[y],x,get_lca(nf[y],x));
    }
    
    int totclose;
    int main() {
    #ifdef DEBUG
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    #endif
        memset(g,-1,sizeof(-1));
        read(n); nowsz=n;
        for(int i=1;i<n;i++) {
            int u,v;
            read(u); read(v);
            add(u,v);
        }
        dfs1(1,0);
        get_root(1,0); 
        get_devide(rt,0);
        read(Q); totclose=n;
        while(Q--) {
            scanf("%s",o);
            if(o[0]=='C') {
                int x;
                read(x);
                if(clo[x]==1) {
                    clo[x]=0;
                    open(x,x,0);
                    totclose++;
                }
                else {
                    clo[x]=1;
                    close(x,x,0);
                    totclose--;
                }
            }
            else {
                if(totclose==1) puts("0");
                else if(totclose==0) puts("-1");
                else {
                    Node tp=*mx.begin();
                    int ans=tp.fi+tp.se;
                    printf("%d
    ",ans);    
                }
            } 
        }
        return 0;
    }
    /*
    5
    1 2
    2 3
    1 4
    2 5
    10
    C 5
    C 3
    C 2
    G
    */
    View Code
    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    using namespace std;
    #define ll long long
    #define db double
    const int n=5,m=10;
    
    char cc; ll ff;
    template<typename T>void read(T& aa) {
        aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main() {
        srand((unsigned)time(NULL));
        printf("%d
    ",n);
        for(int i=2;i<=n;i++) {
            int fa=rand()%(i-1)+1;
            printf("%d %d
    ",fa,i);
        } 
        printf("%d
    ",m);
        for(int i=1;i<=m;i++) {
            int x=rand()%n+1;
            int o=rand()%2;
            if(!o) puts("G");
            else printf("C %d
    ",x);
        }
        return 0;
    }
    rand
  • 相关阅读:
    一分钟搞懂列式与行式数据库(转)
    docker daemon 配置文件
    Docker-删除untagged docker images
    全栈JavaScript之路(十三)了解 ElementTraversal 规范
    static, readonly, const
    Timer与AlarmManager的差别
    计算客 (人人都有极客精神)爆力
    nginx 配置web 虚拟文件夹 而且codeIgniter,thinkphp 重定向url 地址
    单例模式之 懒汉模式普通版
    POJ 3468 A Simple Problem with Integers 【树状数组】
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8511654.html
Copyright © 2020-2023  润新知