• 解题:ZJOI 2015 幻想乡战略游戏


    题面

    神**所有点都爆int,我还以为我写出什么大锅了,不开long long见祖宗。。。

    动态点分治利用点分树树高不超过log的性质,我们对每个点维护一个子树和,一个点分树子树和,一个点分树上父亲的子树和。修改直接爬点分树,查询在点分树上往答案较小的儿子上跳,如果儿子都不如自己优说明自己就是最优的

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=100005,inf=1e9;
      6 int n,c,T,t1,t2,t3,cnt,Cnt,sizz;
      7 int p[N],noww[2*N],goal[2*N],val[2*N];
      8 int siz[N],dep[N],far[N],imp[N],top[N],dis[N];
      9 int P[N],Noww[2*N],Goal[2*N],Val[2*N];
     10 int sze[N],maxx[N],vis[N],fer[N];
     11 long long sum[N],dst[N][2];
     12 void Link(int f,int t,int v)
     13 {
     14     noww[++cnt]=p[f],p[f]=cnt;
     15     goal[cnt]=t,val[cnt]=v;
     16     noww[++cnt]=p[t],p[t]=cnt;
     17     goal[cnt]=f,val[cnt]=v;
     18 }
     19 void Linka(int f,int t,int v)
     20 {
     21     Noww[++Cnt]=P[f],P[f]=Cnt;
     22     Goal[Cnt]=t,Val[Cnt]=v;
     23     Noww[++Cnt]=P[t],P[t]=Cnt;
     24     Goal[Cnt]=f,Val[Cnt]=v;
     25 }
     26 void DFS(int nde,int fth,int dth)
     27 {
     28     int tmp=0;
     29     siz[nde]=1,far[nde]=fth,dep[nde]=dth;
     30     for(int i=p[nde];i;i=noww[i])
     31         if(goal[i]!=fth)
     32         {
     33             dis[goal[i]]=dis[nde]+val[i];
     34             DFS(goal[i],nde,dth+1);
     35             siz[nde]+=siz[goal[i]];
     36             if(siz[goal[i]]>tmp)
     37                 tmp=siz[goal[i]],imp[nde]=goal[i];
     38         }
     39 }
     40 void Gettop(int nde,int tpp)
     41 {
     42     top[nde]=tpp;
     43     if(imp[nde])
     44     {
     45         Gettop(imp[nde],tpp);
     46         for(int i=p[nde];i;i=noww[i])
     47             if(goal[i]!=far[nde]&&goal[i]!=imp[nde])
     48                 Gettop(goal[i],goal[i]);
     49     }
     50 }
     51 int LCA(int x,int y)
     52 {
     53     while(top[x]!=top[y])
     54     {
     55         if(dep[top[x]]<dep[top[y]])
     56             swap(x,y); x=far[top[x]];
     57     }
     58     return dep[x]<dep[y]?x:y;
     59 }
     60 long long Dist(int x,int y)
     61 {
     62     int lca=LCA(x,y);
     63     return dis[x]+dis[y]-2*dis[lca];
     64 }
     65 void Mark(int nde,int fth)
     66 {
     67     sze[nde]=1,maxx[nde]=0;
     68     for(int i=p[nde];i;i=noww[i])
     69         if(goal[i]!=fth&&!vis[goal[i]])
     70         {
     71             Mark(goal[i],nde);
     72             sze[nde]+=sze[goal[i]];
     73             maxx[nde]=max(maxx[nde],sze[goal[i]]);
     74         }
     75     maxx[nde]=max(maxx[nde],sizz-sze[nde]);
     76     if(maxx[nde]<maxx[c]) c=nde;
     77 }
     78 void Create(int nde,int fth)
     79 {
     80     vis[nde]=true,fer[nde]=fth;
     81     for(int i=p[nde];i;i=noww[i])
     82         if(!vis[goal[i]])
     83         {
     84             sizz=sze[goal[i]],maxx[c=0]=sze[goal[i]];
     85             Mark(goal[i],0),Linka(nde,c,goal[i]),Create(c,nde);
     86         }
     87 }
     88 void Change(int nde,int tsk)
     89 {
     90     sum[nde]+=tsk; int mem=nde;
     91     while(fer[nde])
     92     {
     93         long long dist=Dist(fer[nde],mem)*tsk;
     94         dst[fer[nde]][0]+=dist,dst[nde][1]+=dist;
     95         sum[fer[nde]]+=tsk,nde=fer[nde]; 
     96     }
     97 }
     98 long long Getans(int nde)
     99 {
    100     long long ret=dst[nde][0]; int mem=nde;
    101     while(fer[nde])
    102     {
    103         long long dist=Dist(fer[nde],mem);
    104         ret+=dst[fer[nde]][0]-dst[nde][1];
    105         ret+=dist*(sum[fer[nde]]-sum[nde]);
    106         nde=fer[nde];
    107     }
    108     return ret;
    109 }
    110 long long Query(int nde)
    111 {
    112     long long ret=Getans(nde);
    113     for(int i=P[nde];i;i=Noww[i])
    114         if(Getans(Val[i])<ret)
    115             return Query(Goal[i]);
    116     return ret;
    117 }
    118 int main()
    119 {
    120     scanf("%d%d",&n,&T);
    121     for(int i=1;i<n;i++)
    122         scanf("%d%d%d",&t1,&t2,&t3),Link(t1,t2,t3);
    123     DFS(1,0,1),Gettop(1,1);
    124     sizz=n,maxx[c=0]=n,Mark(1,0);
    125     int mem=c; Create(c,0),c=mem;
    126     while(T--)
    127     {
    128         scanf("%d%d",&t1,&t2);
    129         Change(t1,t2),printf("%lld
    ",Query(c)); 
    130     }
    131     return 0;
    132 }
    View Code
  • 相关阅读:
    Linux显示文件内容常用命令
    Linux文件权限和更改权限
    数据存储及恢复的基本原理
    使用jemter发送HTTPS请求
    运行Jmeter时,出现java.util.prefs.WindowsPreferences <init>异常警告
    Server08AD域安装以及推送
    SVN服务器和客户端搭建
    selenium常见操作
    TestNG 入门教程
    ant+TestNG-xslt生成selenium测试报告
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10162606.html
Copyright © 2020-2023  润新知