zoukankan      html  css  js  c++  java
  • bzoj3052 [wc2013]糖果公园

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3052

    http://uoj.ac/problem/58

    【题解】

    树上莫队+带修改,分块大小n^(2/3)即可。

    复杂度O(n^(5/3))

    # include <math.h>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 2e5 + 10, N = 1e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    inline int getint() {
        int x = 0, f = 1; char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') f = 0;
            ch = getchar();
        }
        while(isdigit(ch)) {
            x = (x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }
        return f ? x : -x;
    }
    
    int n, m, Q, V[N], B[N], C[N], t[N];
    int head[N], nxt[M], to[M], tot = 0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    inline void adde(int u, int v) {
        add(u, v), add(v, u);
    }
    
    int BLOCK, bl[M];
    
    struct pa {
        int x, y, p, t;
        pa() {}
        pa(int x, int y, int p, int t) : x(x), y(y), p(p), t(t) {}
        friend bool operator < (pa a, pa b) {
            return bl[a.x] < bl[b.x] || (bl[a.x] == bl[b.x] && bl[a.y] < bl[b.y]) ||
                   (bl[a.x] == bl[b.x] && bl[a.y] == bl[b.y] && a.t < b.t);
        }
    }q[M];
    
    struct paa {
        int x, oc, nc, t;
        paa() {}
        paa(int x, int oc, int nc, int t) : x(x), oc(oc), nc(nc), t(t) {}
    }p[M];
    
    int pn, qn;
    
    int beg[N], end[N], dfn[M], DFN = 0;
    int fa[N][18], dep[N];
    inline void dfs(int x, int fat = 0) {
        beg[x] = ++DFN; dfn[DFN] = x;
        dep[x] = dep[fat] + 1; fa[x][0] = fat;
        for (int i=1; i<=17; ++i) fa[x][i] = fa[fa[x][i-1]][i-1];
        for (int i=head[x]; i; i=nxt[i]) {
            if(to[i] == fat) continue;
            dfs(to[i], x);
        }
        end[x] = ++DFN; dfn[DFN] = x;
    }
    
    inline int lca(int u, int v) {
        if(dep[u] < dep[v]) swap(u, v);
        for (int i=17; ~i; --i) if((dep[u] - dep[v]) & (1<<i)) u = fa[u][i];
        if(u == v) return u;
        for (int i=17; ~i; --i) if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    
    inline bool IN(int L, int R, int x) {
        return L <= x && x <= R;
    }
    
    ll ans[M];
    bool ban[M];
    
    int ti[M];
    ll cnt;
    inline void ADD(int c) {
        t[c] ++;
        cnt += (ll)V[c] * B[t[c]];
    }
    
    inline void DEL(int c) {
        cnt -= (ll)V[c] * B[t[c]];
        t[c] --;
    }
    
    inline void doit(int pos) {
        if(ti[pos] == 0) ADD(C[pos]); 
        else DEL(C[pos]);
        ti[pos] ^= 1;
    }
    
    int main() {
        cin >> n >> m >> Q;
        for (int i=1; i<=m; ++i) V[i] = getint();
        for (int i=1; i<=n; ++i) B[i] = getint();
        for (int i=1, u, v; i<n; ++i) {
            u = getint(), v = getint();
            adde(u, v);
        }
        dfs(1); 
        BLOCK = pow(n, 2.0/3.0);
        for (int i=1; i<=DFN; ++i) bl[i] = (i-1)/BLOCK + 1; 
        for (int i=1; i<=n; ++i) t[i] = C[i] = getint(); 
        for (int i=1, o, tx, ty; i<=Q; ++i) {
            o = getint(); tx = getint(), ty = getint();
            if(o) {
                int LCA = lca(tx, ty); 
                if(beg[tx] > beg[ty]) swap(tx, ty);
                if(LCA == tx) q[++qn] = pa(beg[tx], beg[ty], 0, i);
                else q[++qn] = pa(end[tx], beg[ty], LCA, i);
    //            cout << LCA << endl;
            } else {
                p[++pn] = paa(tx, t[tx], ty, i);
                t[tx] = ty; ban[i] = 1;
            }
        }
        sort(q+1, q+qn+1);
    //    puts("======p======");
    //    for (int i=1; i<=pn; ++i) printf("x = %d, oc = %d, nc = %d, t = %d
    ", p[i].x, p[i].oc, p[i].nc, p[i].t);
    //    puts("======q======");
    //    for (int i=1; i<=qn; ++i) printf("x = %d, y = %d, lca = %d, t = %d
    ", q[i].x, q[i].y, q[i].p, q[i].t);
    //    puts("=============");
        for (int i=1; i<=n; ++i) t[i] = ti[i] = 0;
        int L = 1, R = 0;
        for (int i=1, j=1; i<=qn; ++i) {
            while(j <= pn && q[i].t > p[j].t) {
                if(IN(L, R, beg[p[j].x]) ^ IN(L, R, end[p[j].x])) ADD(p[j].nc), DEL(p[j].oc);
                C[p[j].x] = p[j].nc; ++j;
            }
            while(j-1 >= 1 && q[i].t < p[j-1].t) {
                --j; if(IN(L, R, beg[p[j].x]) ^ IN(L, R, end[p[j].x])) ADD(p[j].oc), DEL(p[j].nc);
                C[p[j].x] = p[j].oc;
            }
    //        printf("i = %d, j = %d
    ", i, j);
            while(L < q[i].x) doit(dfn[L]), ++L;
            while(L > q[i].x) --L, doit(dfn[L]);
            while(R < q[i].y) ++R, doit(dfn[R]);
            while(R > q[i].y) doit(dfn[R]), --R;
            if(q[i].p) doit(q[i].p);
            ans[q[i].t] = cnt;
            if(q[i].p) doit(q[i].p);    
        }
        for (int i=1; i<=Q; ++i) if(!ban[i]) printf("%lld
    ", ans[i]);
        return 0;
    }
    /*
    4 3 5
    1 9 2
    7 6 5 1
    2 3
    3 1
    3 4
    1 2 3 2
    1 1 2
    1 4 2
    0 2 1
    1 1 2
    1 4 2
    */ 
    View Code
  • 相关阅读:
    pigeon
    servlet
    Linux (centos6.5) 安装Node和pm2
    git 常用命令
    git本地仓库推送代码到远程仓库
    linux 服务器 磁盘空间查看清理
    阿里云 Kubenetes容器 时区相差8小时 设置环境变量
    推荐一个简易易懂的ElasticSearch 入门学习站
    ElasticSearch 设置索引mapping 文档类型,重置elastic密码
    linux 查看系统各项指标(资源,内存)
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj3052.html
Copyright © 2011-2022 走看看