• bzoj4765 普通计算姬


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

    【题解】

    我们可以分块来做。

    首先我们预处理每块的答案,并且处理出来f[x,i]表示x改动了,i块有多少个要改动。

    修改用DFS序+BIT来块中暴力,整块用上面的方法处理即可。

    询问块中BIT暴力,整块直接查答案即可。

    # include <stdio.h>
    # include <string.h>
    # 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, BLOCK = 310, N = 1e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, d[M], rt;
    int head[M], 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);
    }
    
    namespace BIT {
        const int M = 4e5 + 10;
        ull c[M];
        int n;
        # define lb(x) (x&(-x)) 
        inline void set(int _n) {
            n = _n; memset(c, 0, sizeof c);
        }
        inline void edt(int x, int d) {
            for (; x<=n; x+=lb(x)) c[x] += d;
        }
        inline ull ask(int x) {
            ull ret = 0;
            for (; x; x-=lb(x)) ret += c[x];
            return ret;
        }
        # undef lb 
    }
    
    ull bans[M]; 
    int bl[M]; 
    int f[N][BLOCK + 100], sz; 
    int in[M], out[M], DFN=0, t[BLOCK + 100]; 
    inline void dfs(int x, int fa) {
        t[bl[x]] ++;
        for (int i=1; i<=sz; ++i) f[x][i] = t[i]; 
        in[x] = ++DFN;
        for (int i=head[x]; i; i=nxt[i]) {
            if(to[i] == fa) continue;
            dfs(to[i], x);
        }
        out[x] = DFN;
        t[bl[x]] --; 
    }
    
    int main() {
        int q; scanf("%d%d", &n, &q);
        BIT::set(n); 
        for (int i=1; i<=n; ++i) scanf("%d", d+i); 
        for (int i=1, u, v; i<=n; ++i) {
            scanf("%d%d", &u, &v); 
            if(u == 0) rt = v;
            else adde(u, v);
            bl[i] = (i-1)/BLOCK+1;
        }
        sz = bl[n]; 
        dfs(rt, 0); 
        for (int i=1; i<=n; ++i) BIT::edt(in[i], d[i]); 
        for (int i=1; i<=n; ++i) bans[bl[i]] += BIT::ask(out[i]) - BIT::ask(in[i]-1); 
        
        int op, x, y;
        while(q--) {
             scanf("%d%d%d", &op, &x, &y);
            if(op == 1) {
                 BIT::edt(in[x], y-d[x]);
                for (int i=1; i<=sz; ++i) bans[i] += (ull)f[x][i]*(y-d[x]);
                d[x] = y; 
            } else {
                ull ans = 0;
                if(bl[x] == bl[y]) {
                    for (int i=x; i<=y; ++i) ans += BIT::ask(out[i]) - BIT::ask(in[i]-1); 
                    printf("%llu
    ", ans); 
                    continue;
                }
                for (int i=bl[x]+1; i<=bl[y]-1; ++i) ans += bans[i];
                for (int i=x; i<=n && bl[i]==bl[x]; ++i) ans += BIT::ask(out[i]) - BIT::ask(in[i]-1);
                for (int i=y; i && bl[i]==bl[y]; --i) ans += BIT::ask(out[i]) - BIT::ask(in[i]-1); 
                printf("%llu
    ", ans); 
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    配置Mysql远程访问
    mysql Access denied for user root@localhost错误处理备忘
    MsSql判断表是否有自增标识
    .net用NPOI生成Word表格
    TensorFlow-卷积
    Java中int与Integer的区别
    由经纬度坐标得到腾讯地图的瓦片/切片行列号
    vs code上配置Scala
    VMware虚拟机上配置CentOS联网
    使用PuTTy在CentOS下安装web.py与简单的文件传输
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4765.html
Copyright © 2020-2023  润新知