• luogu P4115 Qtree4


    题目链接

    luogu P4115 Qtree4

    题解

    动态点分治,和上一题一样.同样三个堆.就是带权,用边权替换深度就好
    为什么要单独写这个题解呢,因为我卡常卡了一天....据说树剖比rmq快? 在第24次AC
    同样也有更有做法

    代码

    #include<queue> 
    #include<cstdio>
    #include<cctype> 
    #include<algorithm>
    
    
    /*char ch;
    char buf[100000],*p1 = buf,*p2 = buf;
    int F = 1;
    #define nc() 
        p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,100000,stdin),p1 == p2) ? EOF :*p1 ++;
    #define read(x)  
        x = 0;ch = nc();F = 1; 
        while(!isdigit(ch)) { if (ch == '-') F = -1; ch = nc();}
        while(isdigit(ch))x = x*10+ch - '0',ch = nc();
        x *= F;
        */
    
    
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    const int MAXIN=3e5;
    char IN[MAXIN],*SS=IN,*TT=IN;
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++) 
    inline int read() {
        int now=0,f=1;register char c=gc();
        for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
        for(;isdigit(c);now=now*10+c-'0',c=gc());
        return now*f;
    } 
    
    #define INF 998244353 
    const int maxn = 100007;  
    
    int son[maxn],f[maxn],mn[maxn << 1][25],root,tot; 
    struct node { 
        int u,v,next,w; 
    } edge[maxn << 1]; 
    int head[maxn],num = 0;
    inline void add_edge(int u,int v,int w) { 
        edge[++ num].v = v;edge[num].next = head[u];head[u] = num;
        edge[num].w = w; 
    }  
    int n; 
    int lg[maxn << 1],dfn;// = 0; 
    bool col[maxn]; 
    
    struct Heap { 
        std::priority_queue<int>A,B;
        inline void push(int x) { A.push(x); } 
        inline void erase(int x) { B.push(x); } 
        inline void pop() { while(B.size() && A.top() == B.top())  A.pop(),B.pop();	A.pop();  } 
        inline int top() { 
            while(B.size() && A.top() == B.top()) A.pop(),B.pop(); 
            return A.top(); 
        } 
        inline int size() { return A.size() - B.size();  } 
        int retop() { if(size() < 2) return 0;int x = top();pop();int ret = top();push(x);return ret;} 
    } b[maxn],c[maxn],ans;
    inline void insert(Heap &s) {if(s.size() > 1)ans.push(s.top() + s.retop());} 
    inline void dele(Heap &s) {if(s.size() > 1) ans.erase(s.top() + s.retop());} 
    
    int pos[maxn],Dis[maxn]; 
    int id[maxn],tm;  
    
    void dfs_rmq (int x,int fa) { 
        int t = ++ tm; mn[pos[x] = ++ dfn][0] = tm,id[t] = x; 
        for(int i = head[x];i;i = edge[i].next) { 
            int v = edge[i].v; 
            if(v == fa)continue; 
            Dis[v] = Dis[x] + edge[i].w;
            dfs_rmq(v,x); 
            mn[++ dfn][0] = t; //访问完子树后加上Qwq
        } 
    } 
    inline int lca(int x,int y) { 
        x = pos[x];y = pos[y]; 
        if(y < x) std::swap(x,y); 
        int k = lg[y - x + 1]; 
        return id[std::min(mn[x][k],mn[y - (1 << k) + 1][k])]; 
    } 
    inline int dis(int x,int y) { 
        return Dis[x] + Dis[y] - 2 * Dis[lca(x,y)]; 
    } 
    bool vis[maxn];int fa[maxn]; 
    void get_root(int x,int fa) { 
        son[x] = 1; f[x] = 0; 
        for(int i = head[x];i;i = edge[i].next) { 
            int v = edge[i].v; 
            if(v == fa || vis[v]) continue; 
            get_root(v,x); 
            son[x] += son[v];f[x] = std::max(f[x],son[v]); 
        } 
        f[x] = std::max(f[x],tot - son[x]); 
        if(f[x] < f[root]) root = x; 
    } 
    void get(int x,int Fa,int rt) { 
        b[root].push(dis(x,fa[root]));  
        for(int i = head[x];i;i = edge[i].next) { 
            int v = edge[i].v; if(v == Fa || vis[v]) continue;
            get(v,x,rt); 
        } 
    } 
    void build(int x,int Fa) { 
        fa[x] = Fa;vis[x] = 1; 
        c[x].push(0); 
        get(x,0,Fa); 
        for(int i = head[x];i;i = edge[i].next) {
            int v = edge[i].v;
            if(!vis[v] && v != Fa) { 
                tot = son[edge[i].v];root = 0;f[0] = INF; 
                get_root(edge[i].v,x);
                v = root; 
                build(root,x); 
                c[x].push(b[v].top());  
            }  
        }	
        insert(c[x]); 
    } 
    void turn(int x,bool type) { 
        dele(c[x]); 
        if(type) c[x].erase(0); 
        else c[x].push(0); 
        insert(c[x]);
        for(int i = x;i;i = fa[i]) {
            dele(c[fa[i]]); 
            //printf("%d ",i); 
            if(b[i].size())	c[fa[i]].erase(b[i].top()); 
            if(type)b[i].erase(dis(x,fa[i])); else b[i].push(dis(x,fa[i])); 
            if(b[i].size()) c[fa[i]].push(b[i].top()); 
            insert(c[fa[i]]); 
        } 
        //puts("");
    } 
    
    inline char get(){
        char c=gc();
        while(c!='A'&&c!='C') c=gc();
        return c;
    } 
    int main() { 
         n = read();  
         //read(n); 
         for(int u,v,w,i = 1;i < n;++ i) {  
            u = read(),v = read(),w = read();  
            //read(u);read(v);read(w); 
            add_edge(u,v,w);add_edge(v,u,w);  
        }  
        dfs_rmq(1,0);  
        for(int i = 2;i <= dfn;++ i) lg[i] = lg[i >> 1] + 1; 
        for(int i = 1;i <= lg[dfn];++ i) 
      		for(int j = dfn - (1 << i - 1);j;-- j) 
      			mn[j][i] = std::min(mn[j][i - 1],mn[j + (1 << i - 1)][i - 1]); 
      	f[0] = INF; root = 0; tot = n; 
        get_root(1,0); 
        build(root,0); 
        //char opt[10]; 
        int Q = read(); 
        
        int sum = n; 
        for(int asd;Q --;) { 
            //scanf("%s",opt + 1); 
            if(get() == 'C') { 
                asd = read();//read(asd); 
                if(col[asd]) turn(asd,0), sum ++,col[asd] = 0; 
                else turn(asd,1),sum --,col[asd] = 1;
            } 
            else  { 
                if(sum == 1)puts("0"); 
                else if(!sum)puts("They have disappeared."); 
                else printf("%d
    ",std::max(0,ans.top())); 
            } 
        } 
        return 0; 
    } 
    
  • 相关阅读:
    Rational Rose 2003 逆向工程转换C++ / VC++ 6.0源代码成UML类图
    用VC实现特定编辑框上对回车键响应
    22.职责链模式
    21.策略模式
    20.状态模式
    19.解释器模式
    18.备忘录模式
    17.中介者模式
    16.观察者模式
    15.迭代器模式
  • 原文地址:https://www.cnblogs.com/sssy/p/9249373.html
Copyright © 2020-2023  润新知