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


    题目描述

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

    在打仗之前,幽香现在面临一个非常基本的管理问题需要解决。 整个地图是一个树结构,一共有n块空地,这些空地被n-1条带权边连接起来,使得每两个点之间有一条唯一的路径将它们连接起来。

    在游戏中,幽香可能在空地上增加或者减少一些军队。同时,幽香可以在一个空地上放置一个补给站。 如果补给站在点u上,并且空地v上有dv个单位的军队,那么幽香每天就要花费dv*dist(u,v)的金钱来补给这些军队。

    由于幽香需要补给所有的军队,因此幽香总共就要花费为Sigma(Dv*dist(u,v),其中1<=V<=N)的代价。其中dist(u,v)表示u个v在树上的距离(唯一路径的权和)。

    因为游戏的规定,幽香只能选择一个空地作为补给站。在游戏的过程中,幽香可能会在某些空地上制造一些军队,也可能会减少某些空地上的军队,进行了这样的操作以后,出于经济上的考虑,幽香往往可以移动他的补给站从而省一些钱。

    但是由于这个游戏的地图是在太大了,幽香无法轻易的进行最优的安排,你能帮帮她吗? 你可以假定一开始所有空地上都没有军队。

    输入输出格式

    输入格式:

    第一行两个数n和Q分别表示树的点数和幽香操作的个数,其中点从1到n标号。 接下来n-1行,每行三个正整数a,b,c,表示a和b之间有一条边权为c的边。 接下来Q行,每行两个数u,e,表示幽香在点u上放了e单位个军队(如果e<0,就相当于是幽香在u上减少了|e|单位个军队,说白了就是 du←du+e)。数据保证任何时刻每个点上的军队数量都是非负的。

    输出格式:

    对于幽香的每个操作,输出操作完成以后,每天的最小花费,也即如果幽香选择最优的补给点进行补给时的花费。

    输入输出样例

    输入样例#1: 复制
    10 5
    1 2 1
    2 3 1
    2 4 1
    1 5 1
    2 6 1
    2 7 1
    5 8 1
    7 9 1
    1 10 1
    3 1
    2 1
    8 1
    3 1
    4 1
    输出样例#1: 复制
    0
    1
    4
    5
    6

    说明

    对于所有数据,1<=c<=1000, 0<=|e|<=1000, n<=10^5, Q<=10^5 非常神奇的是,对于所有数据,这棵树上的点的度数都不超过20,且N,Q>=1

    建出点分树,直接用动态点分治即可,不需要配合高级数据结构。

    注意lg[]对数表预处理的范围是[1,2n]的。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=l; i<=r; i++)
     4 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=200100,inf=1000000000;
     9 int n,Q,x,y,u,v,w,rt,lg[N],a[N],pos[N],vis[N],st[N][20],tot,fa[N],f[N],sz[N],d[N];
    10 ll dis1[N],dis2[N],sm[N];
    11 
    12 struct E{
    13     int to[N<<1],nxt[N<<1],h[N],val[N<<1],cnt;
    14     void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; }
    15     void find(int x,int fa,int S,int &rt){
    16         sz[x]=1; f[x]=0;
    17         For(i,x) if ((k=to[i])!=fa && !vis[k])
    18             find(k,x,S,rt),sz[x]+=sz[k],f[x]=max(f[x],sz[k]);
    19         f[x]=max(f[x],S-sz[x]);
    20         if (f[x]<=f[rt]) rt=x;
    21     }
    22     void dfs(int x,int fa){
    23         pos[x]=++tot; a[tot]=d[x];
    24         For(i,x) if (fa!=(k=to[i])) d[k]=d[x]+val[i],dfs(k,x),a[++tot]=d[x];
    25     }
    26 }G,G1;
    27 
    28 void build(int x){
    29     vis[x]=1;
    30     for (int i=G.h[x],k; i; i=G.nxt[i]) if (!vis[k=G.to[i]]){
    31         int rt=0; f[rt]=inf; G.find(k,0,sz[k],rt); G1.add(x,rt,k); fa[rt]=x; build(rt);
    32     }
    33 }
    34 
    35 void getst(){
    36     rep(i,1,tot) st[i][0]=a[i];
    37     for (int j=1; j<=18; j++)
    38         rep(i,1,tot-(1<<j)+1) st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    39 }
    40 
    41 int que(int l,int r){ int t=lg[r-l+1]; return min(st[l][t],st[r-(1<<t)+1][t]); }
    42 int dis(int x,int y){ int a=pos[x],b=pos[y]; if (a>b) swap(a,b); return d[x]+d[y]-2*que(a,b); }
    43 
    44 void ins(int x,int k){
    45     sm[x]+=k;
    46     for (int i=x; fa[i]; i=fa[i]){
    47         int D=dis(fa[i],x);
    48         dis1[fa[i]]+=1ll*D*k; dis2[i]+=1ll*D*k; sm[fa[i]]+=k;
    49     }
    50 }
    51 
    52 ll calc(int u){
    53     ll ans=dis1[u];
    54     for (int i=u; fa[i]; i=fa[i]){
    55         int D=dis(fa[i],u); ans+=dis1[fa[i]]-dis2[i]; ans+=D*(sm[fa[i]]-sm[i]);
    56     }
    57     return ans;
    58 }
    59 
    60 ll que(int u){
    61     ll ans=calc(u);
    62     for (int i=G1.h[u]; i; i=G1.nxt[i]){
    63         ll tmp=calc(G1.val[i]);
    64         if (tmp<ans) return que(G1.to[i]);
    65     }
    66     return ans;
    67 }
    68 
    69 int main(){
    70     scanf("%d%d",&n,&Q);
    71     lg[1]=0; rep(i,2,200010) lg[i]=lg[i>>1]+1;
    72     rep(i,1,n-1) scanf("%d%d%d",&u,&v,&w),G.add(u,v,w),G.add(v,u,w);
    73     G.dfs(1,0); getst(); f[rt=0]=inf; G.find(1,0,n,rt); build(rt);
    74     while (Q--) scanf("%d%d",&x,&y),ins(x,y),printf("%lld
    ",que(rt));
    75     return 0;
    76 }
  • 相关阅读:
    Framework7-Vue搭建项目
    在vue中使用handsontable
    electron-vue中关闭烦人的es语法检查
    今天工作整整一个月了,来记录一下(web前端)
    在electron-vue项目中使用element-ui
    使用electron-vue搭建桌面应用程序项目
    Electron是个啥?
    2月11日-寒假进度11
    2月10日-寒假进度10
    2月9日-寒假进度09
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8505920.html
Copyright © 2020-2023  润新知