0、题意:动态维护带权中心

1、分析:妈的,这题做了一天,mdzzzzzzzzzzzzzzzzzz…..

这个题是边权,我们首先要将边权转化成点权。。。

我们维护一个分支结构中到根的距离和,一个分支结构中到分支中心的距离和,这个分支结构中所有的军队总量,lca…,lca这个预处理出来,因为要求树上两点距离

询问到一个点的距离时(下面称query值),我们在logn个分治结构中询问答案

到x点的答案=x本身子树到这个点答案,然后我们向上跳

每次跳我们将答案+=father[x]的除了x这个子树的点到father[x]的值+这些点的value*father[x]到x的值。。口胡了一番。。具体看代码吧

修改的时候,也是修改logn个分支结构,我们依旧是随便的修改一下就可以了

然后在真正的询问怎么办呢?我们logn的搞一下,怎么搞呢?我们贪心

如果这个子树中的根的query值<这个根的query,那么我们就一下子跳到这个子树中的分支中心去,可以想象,我们要找的点必然在这个子树中。

我们最多会跳logn次,每次我们查询query值是O(logn)的,所以询问的时间复杂度是O(log2n),修改的时间复杂度是O(logn),总的复杂度O(nlog2n)

代码改了一天QAQ

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define M 200010

inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

struct Edge{
    int u, v;
    LL w;
    int next;
} G[M];
int head[M], tot;
int size[M], mx[M], mi, root;
int ok[M];
int father[M];
LL fadis[M], dis;
LL ft[M];
LL s1[M], s2[M], val[M];
int fenzhi[M][20], ding[M];
int vis[M];
int n, Q;
int zz[M], ztot;
int ftt[M][20];
LL ff[M][20];
int height[M];
LL dep[M];
int pa[M];

inline void add(int u, int v, LL w){
    G[++ tot] = (Edge){u, v, w, head[u]};
    head[u] = tot;
}

inline void dfs(int x, int fa, int h, LL gh){
    height[x] = h;
    dep[x] = gh;
    ftt[x][0] = fa;
    for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa){
        dfs(G[i].v, x, h + 1, gh + G[i].w);
    }
}

inline int lca(int x, int y){
    if(height[x] < height[y]) swap(x, y);
    int t = height[x] - height[y];
    for(int i = 18; i >= 0; i --){
        if(t & (1 << i)){
            x = ftt[x][i];
        }
    }
    if(x == y) return x;
    for(int i = 18; i >= 0; i --){
        if(ftt[x][i] != ftt[y][i]){
            x = ftt[x][i];
            y = ftt[y][i];
        }
    }
    return ftt[x][0];
}

inline void init(){
    for(int i = 1; i <= 18; i ++){
        for(int j = 1; j <= n; j ++){
            ftt[j][i] = ftt[ftt[j][i - 1]][i - 1];
        }
    }
    for(int i = 1; i <= n; i ++){
        int o = i, cnt = 0;
        while(o){
            int LCA = lca(o, i);
            LL od = dep[i] + dep[o] - 2 * dep[LCA];
            ff[i][cnt] = od;
            o = father[o];
            cnt ++;
        }
    }
}

inline void dfssize(int x, int fa){
    size[x] = 1; mx[x] = 0;
    for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa && !ok[G[i].v]){
        dfssize(G[i].v, x);
        size[x] += size[G[i].v];
        if(size[G[i].v] > mx[x]) mx[x] = size[G[i].v];
    }
}

inline int getroot(int r, int x, int fa, LL d){
    mx[x] = max(mx[x], size[r] - size[x]);
    if(mx[x] < mi) mi = mx[x], root = x, dis = d;
    for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa && !ok[G[i].v]){
        getroot(r, G[i].v, x, d + G[i].w);
    }

}

inline int solve(int x, int fa, LL d, int otot){
    mi = n; dfssize(x, 0);
    getroot(x, x, 0, 0);
    ok[root] = 1;
    father[root] = fa;
    int op = root;
    dis += d;
    fadis[root] = dis;
    LL tt = dis;
    for(int i = head[root]; i != -1; i = G[i].next) if(!ok[G[i].v]){
        int wt = solve(G[i].v, op, G[i].w, otot + 1);
        ft[wt] = G[i].w;
        fenzhi[G[i].v][otot] = wt;
        ding[wt] = G[i].v;
    }
    return op;
}

inline LL query(int x){
    LL ret = s1[x];
    int o = x;
    int cnt = 1;
    while(father[o]){
        ret += (s1[father[o]] - (s2[o] + ft[o] * val[o]) + (val[father[o]] - val[o]) * ff[x][cnt]);
        o = father[o];
        cnt ++;
    }
    return ret;
}

inline int Query(int rt, int fa, int otot){
    LL yy = query(rt);
    for(int i = head[rt]; i != -1; i = G[i].next) if(fenzhi[G[i].v][otot] != fa){
        LL y = query(G[i].v);
        if(yy > y) return Query(fenzhi[G[i].v][otot], rt, otot + 1);
    }
    int x = rt;
    return x;
}

inline int change(int x, int y, int rt){
    int o = father[x];
    int cnt = 1;
    val[x] += y;
    s2[x] += (ff[x][cnt] - ft[x]) * y;
    while(o){
        s1[o] += (ff[x][cnt]) * y;
        s2[o] += (ff[x][cnt + 1] - ft[o]) * y;
        val[o] += y;
        o = father[o];
        cnt ++;
    }
    int ret = Query(rt, 0, 0);
    return ret;
}

int main(){
    n = read(), Q = read();
    memset(head, -1, sizeof(head));
    for(int i = 1; i < n; i ++){
        int u = read(), v = read();
        LL w = (LL)read();
        add(u, v, w); add(v, u, w);
    }
    dfs(1, 0, 0, 0);
    int rt = solve(1, 0, 0, 0); fadis[rt] = 0;
    init();
    for(int i = 1; i <= Q; i ++){
        int u = read();
        LL e = read();
        printf("%lld\n", query(change(u, e, rt)));
    }
    return 0;
}

BZOJ3924——[Zjoi2015]幻想乡战略游戏的更多相关文章

  1. BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】

    BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...

  2. bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

  3. BZOJ3924 [Zjoi2015]幻想乡战略游戏

    Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...

  4. [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)

    题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...

  5. 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

  6. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

  7. 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告

    P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...

  8. [ZJOI2015]幻想乡战略游戏——动态点分治

    [ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...

  9. AC日记——[ZJOI2015]幻想乡战略游戏 洛谷 P3345

    [ZJOI2015]幻想乡战略游戏 思路: 树剖暴力转移: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1 ...

随机推荐

  1. omnet++5.0安装使用

    1.下载Windows安装包,5.0的omnetpp-5.0-src-windows.zip 2.解压到d盘 3.D:\omnetpp-5.0\doc找到这个目录,下面有个InstallGuide.p ...

  2. Linux系统信息查看命令大全

    系统# uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo # 查看CPU信息# hostna ...

  3. 比较oracle数据的表结构

    对比不同用户对象的异同,同时生成sql语句或直接提交到数据库,powerdesinger的比较实在是麻烦. pl/sql为我们提供了很好的工具 在pl/sql中的工具下“比较用户对象”,下即可实现:

  4. Java实例分析:宠物商店

    设计一个“宠物商店”,在宠物商店中可以有多种宠物,试表示出此种关系,并要求可以根据宠物的关键字查找相应的宠物信息. //======================================== ...

  5. Nginx实现简易泛域名CDN节点

    如何使用Nginx泛域名解析+反向代理+静态资源缓存呢? 安装nginx,安装过程不再赘述,记得带上pcre.gzip.sub.status这几个模块,另外如果想开通在线清理缓存功能,需要安装ngx_ ...

  6. docker快速启动脚本

    #!/bin/sh PID=$(docker inspect --format "{{.State.Pid}}" $1) nsenter -t $PID -u -i -n -p n ...

  7. GitHub 在 Clion2016.1.3 中的设置

    1.在 GitHub 上注册,建立一个 Repositories,结果获得如下 https://github.com/GPerelman/Clion2016.1.3.git 2.打开 git-bash ...

  8. Using Flash Builder with Flash Professional

    http://help.adobe.com/en_US/flashbuilder/using/WSc5cd04c102ae3e97-6e5d439512e1414e588-8000.html

  9. 在 docker中 运行 mono /jexus server 并部署asp.net mvc站点

    http://linuxdot.net/bbsfile-3988 1.  安装 docker:      // docker 1.7 新版 安装非常容易,理论上说,在主流的任意linux发行版上都可以 ...

  10. Spring与Quartz的整合实现定时任务调度 以及crontab的用法

    最近在研究Spring中的定时任务功能,最好的办法当然是使用Quartz来实现.对于一个新手来说,花了我不少时间,这里我写个笔记,给大家参考. 我使用的是Maven来管理项目,需要的Jar包我给大家贴 ...