=v=

因为外来的入侵,国王决定在某些城市加派士兵。所有城市初始士兵数量为0。当城市 被加派了k名士兵时。城市i的所有子城市需要被加派k+1名士兵。这些子城市的所有子城市需要被加派k+2名士兵。以此类推。

当然,加派士兵的同时,国王也需要不断了解当前的情况。于是他随时可能询问以城市i为根的子树中的所有城市共被加派了多少士兵。

你现在是国王的军事大臣,你能回答出国王的每个询问么?

= =

对于50%的数据,1<=n<=1000,1<=p<=300

对于100%的数据,1<=n<=50000,1<=p<=100000,1<=x<=n,0<=k<=1000

=w=

给第i点增加k个士兵,实际上一共增加了k*size[i]+w[i]。

其中w[i]是一个定值,可以O(n)预处理出来。


给原树转成dfs序后,

考虑询问一个点,它的贡献来源:

1.它及其儿子加的所有士兵:显然可以使用单点修改,区间询问的数据结构来维护;

2.其祖先加了士兵:祖先加的士兵会增加深度差后再传给这个点,所以用区间修改,单点询问的数据结构来维护三个东西:

  1. (1)有多少个祖先加了士兵
  2. (2)加的士兵总和
  3. (3)祖先的总深度

OTZ

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<algorithm>
  5. #include<math.h>
  6. #define ll long long
  7. using namespace std;
  8. const char* fin="truetears.in";
  9. const char* fout="truetears.out";
  10. const ll inf=0x7fffffff;
  11. const ll maxn=50007,maxm=maxn*2,maxt=maxn*4;
  12. ll n,m,i,j,k;
  13. ll fi[maxn],ne[maxm],la[maxm],tot;
  14. ll a[maxn],ans;
  15. ll fa[maxn],de[maxn],w[maxn],dfn[maxn],low[maxn],si[maxn];
  16. char ch;
  17. ll c[maxn],d[maxn][3],mk[maxt][3],num;
  18. void change(ll v,ll v1){
  19. for (;v<=n;v+=v&-v) c[v]+=v1;
  20. }
  21. ll getsum(ll v){
  22. ll k=0;
  23. for (;v;v-=v&-v) k+=c[v];
  24. return k;
  25. }
  26. ll getsum(ll l,ll r){
  27. return getsum(r)-getsum(l-1);
  28. }
  29. void markdown(ll l,ll r,ll t){
  30. if (l==r){
  31. d[l][0]+=mk[t][0];
  32. d[l][1]+=mk[t][1];
  33. d[l][2]+=mk[t][2];
  34. }else{
  35. mk[t*2][0]+=mk[t][0];
  36. mk[t*2][1]+=mk[t][1];
  37. mk[t*2][2]+=mk[t][2];
  38. mk[t*2+1][0]+=mk[t][0];
  39. mk[t*2+1][1]+=mk[t][1];
  40. mk[t*2+1][2]+=mk[t][2];
  41. }
  42. mk[t][0]=mk[t][1]=mk[t][2]=0;
  43. }
  44. void modify(ll l,ll r,ll t,ll v,ll u,ll v1,ll v2){
  45. ll mid=(l+r)/2;
  46. markdown(l,r,t);
  47. if (l>v2 || r<v1) return;
  48. if (l>=v1 && r<=v2){
  49. mk[t][0]+=v;
  50. mk[t][1]++;
  51. mk[t][2]+=u;
  52. return;
  53. }
  54. modify(l,mid,t*2,v,u,v1,v2);
  55. modify(mid+1,r,t*2+1,v,u,v1,v2);
  56. }
  57. void update(ll l,ll r,ll t,ll v){
  58. ll mid=(l+r)/2;
  59. markdown(l,r,t);
  60. if (l==r) return;
  61. if (v<=mid) update(l,mid,t*2,v);
  62. else update(mid+1,r,t*2+1,v);
  63. }
  64. void add_line(ll a,ll b){
  65. tot++;
  66. ne[tot]=fi[a];
  67. la[tot]=b;
  68. fi[a]=tot;
  69. }
  70. void getw(ll v,ll from){
  71. ll i,j,k;
  72. de[v]=de[from]+1;
  73. si[v]=1;
  74. dfn[v]=++num;
  75. for (k=fi[v];k;k=ne[k])
  76. if (la[k]!=from){
  77. getw(la[k],v);
  78. w[v]+=w[la[k]]+si[la[k]];
  79. si[v]+=si[la[k]];
  80. }
  81. low[v]=num;
  82. }
  83. int main(){
  84. freopen(fin,"r",stdin);
  85. freopen(fout,"w",stdout);
  86. scanf("%d%d",&n,&m);
  87. for (i=2;i<=n;i++){
  88. scanf("%d",&j);
  89. fa[i]=j;
  90. add_line(j,i);
  91. add_line(i,j);
  92. }
  93. getw(1,0);
  94. scanf("\n");
  95. for (i=1;i<=m;i++){
  96. scanf("%c%d",&ch,&j);
  97. if (ch=='A'){
  98. scanf("%d\n",&k);
  99. change(dfn[j],si[j]*k+w[j]);
  100. if (dfn[j]==low[j]) continue;
  101. modify(1,n,1,k,de[j],dfn[j]+1,low[j]);
  102. }else{
  103. scanf("\n");
  104. ans=getsum(dfn[j],low[j]);
  105. update(1,n,1,dfn[j]);
  106. ans+=(d[dfn[j]][0]+d[dfn[j]][1]*de[j]-d[dfn[j]][2])*si[j]+w[j]*d[dfn[j]][1];
  107. printf("%lld\n",ans);
  108. }
  109. }
  110. return 0;
  111. }

=o=

考虑贡献的来源。

【JZOJ4895】【NOIP2016提高A组集训第16场11.15】三部曲的更多相关文章

  1. JZOJ 【NOIP2016提高A组集训第16场11.15】兔子

    JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...

  2. JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线

    JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...

  3. 【JZOJ4894】【NOIP2016提高A组集训第16场11.15】SJR的直线

    题目描述 数据范围 解法 考虑逐次加入每一条直线. 对于当前已加入的直线集合L,现在要新加入一条直线l. 那么它产生的贡献,与平行线有关. 对于任意三条直线,如果其中任意两条平行,那么将不做贡献. 所 ...

  4. 【JZOJ4896】【NOIP2016提高A组集训第16场11.15】兔子

    题目描述 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子窝之 ...

  5. 【JZOJ4898】【NOIP2016提高A组集训第17场11.16】人生的价值

    题目描述 NiroBC终于找到了人生的意义,可是她已经老了,在新世界,没有人认识她,她孤独地在病榻上回顾着自己平凡的一生,老泪纵横.NiroBC多么渴望再多活一会儿啊! 突然一个戴着黑色方框眼镜,方脸 ...

  6. 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度

    题目描述 雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路.雪之女王赋予了每一座城市不同的能量,其中第i座城 ...

  7. 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目描述 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 数据范围 40%的数据满足: ...

  8. 【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...

  9. 【NOIP2016提高A组集训第14场11.12】随机游走

    题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...

随机推荐

  1. leyou_06_Nginx的自启

    1.在linux系统的/etc/init.d/目录下创建nginx文件 vim /etc/init.d/nginx 添加以下内容 #!/bin/sh # # nginx - this script s ...

  2. k8s 内部各个部件运转

    Master节点部署的都是kubernetes的核心模块APIServer提供资源操作的唯一入口,并且提供认证/授权/kubernets的访问控制可以通过kubectl和自己开发的客户端,通过http ...

  3. 原 JEECMS导入IDEA进行二次开发图文教程

    JEECMS导入IDEA进行二次开发图文教程 2017年05月15日 17:03:53 Swain_Ho 阅读数 3257    版权声明:本文为博主原创文章,未经博主允许不得转载. https:// ...

  4. Spring AOP(一)--基本概念

    AOP(Aspect Oriented Programing),意为面向切面编程,其实看了很多书本的介绍和说明,我觉得这些解释都太过书面,也可能是翻译的原因,总觉得还是不太懂,也难以理解这种叫法,尤其 ...

  5. 【DM8168学习笔记5】EZSDK目录结构

    EZSDK5.02的目录结构与之前的版本不同,之前的版本各个组件都放在/ezsdk目录下,5.02做了整合. 之前版本:(图片摘自:3.DM816x_1-day_Workshop-Getting_St ...

  6. jmeter断言步骤

    在POST /wordpress/wp-login.php请求,也就是名称为submit login form user的请求上点右键, 选择添加 -> 后置处理器 -> CSS/JQue ...

  7. TZOJ 4021 Ugly Problem(线段树区间子段最大)

    描述 给定一个序列A[0],A[1],…A[N-1],要求找到p0,p1,p2,p3使得A[p0]+A[p0+1]+…+A[p1] + A[p2]+A[p2+1]+…+A[p3]最大(0<=p0 ...

  8. Linux下读写UART串口的代码

    Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下- 两个实用的函数- //////////////// ...

  9. (转)Json在Unity中的简单使用

    Json数据解析在Unity3d中的应用 最近做项目过程中因为Json文件名写错了一个字母Unity报错,找错误找到半夜,当时为了验错,写了一个小Demo,正好借此总结一下Json. 1.什么是Jso ...

  10. Leetcode8.String to Integer (atoi)字符串转整数(atoi)

    实现 atoi,将字符串转为整数. 该函数首先根据需要丢弃任意多的空格字符,直到找到第一个非空格字符为止.如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字 ...