题面在这里>>>

解题思路:

开始写了个LCT后来发现是错的QAQ

正解是动态点分治。

对于一个点,其答案就是$\sum_{i=1}^{n}sum_{i}^{2}$

很神奇地构造出这个式子$\sum_{i=1}^{n}sum_{i}*(Sum_{tot}-sum_{i})$

其中Sumtot是一棵树的总权值和。

可以发现它对于一颗树来说是一个定值。

因为它可以理解成一条边两端选点。

将它拆开,就变成了$\sum_{i=1}^{n}{sum_{i}*Sum_{tot}}-\sum_{i=1}^{n}sum_{i}^{2}$

既然整体是定值,不如在根为1的时候构建,然后维护。

然后算前面那个东西就好了。

厉害就厉害在这里,前面那个东西是可以$O(nlog_{2}n)$计算的。

再来构造一次,这个东西将常数项提出去$Sum_{tot}*{\sum_{i=1}^{n}{sum_{i}}}$

显然那个Sumtot是可以$O(1)$维护的。

后面那个呢?

设当前根为$root$

可以发现对于每一个值产生贡献时在且仅在其父及祖先节点处生效。

所以一共生效了$\mathit{deep_{i}+1}$次

所以说如果设边权为1那么$deep_{i}={\mathit{Dis(i,root)}}$

那么原式就成为了${\sum_{i=1}^{n}{val_{i}}}+{\sum_{i=1}^{n}{\mathit{Dis(i,root)}}}$

剩下的部分和幻想乡那道题就一样了。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 typedef long long lnt;
  5 const int N=200010;
  6 struct pnt{
  7     int hd;
  8     int fa;
  9     int dp;
 10     int wgt;
 11     lnt val;
 12     lnt sum;
 13     lnt Sum;
 14     int eind;
 15     lnt diss;
 16     lnt disf;
 17     bool vis;
 18 }p[N];
 19 struct ent{
 20     int twd;
 21     int lst;
 22 }e[N<<1];
 23 int rt;
 24 int n,m;
 25 int cnt;
 26 int dfn;
 27 int tdn;
 28 int root;
 29 int size;
 30 int maxsize;
 31 int lg[N<<2];
 32 int eula[N<<2][21];
 33 lnt w;
 34 lnt V;
 35 lnt val[N];
 36 void ade(int f,int t)
 37 {
 38     cnt++;
 39     e[cnt].twd=t;
 40     e[cnt].lst=p[f].hd;
 41     p[f].hd=cnt;
 42     return ;
 43 }
 44 void E_dfs(int x,int f)
 45 {
 46     eula[++dfn][0]=x;
 47     p[x].eind=dfn;
 48     p[x].dp=p[f].dp+1;
 49     for(int i=p[x].hd;i;i=e[i].lst)
 50     {
 51         int to=e[i].twd;
 52         if(to==f)
 53             continue;
 54         E_dfs(to,x);
 55         p[x].wgt+=p[to].wgt;
 56         eula[++dfn][0]=x;
 57     }
 58     return ;
 59 }
 60 void Add_dfs(int x,int f)
 61 {
 62     p[x].Sum=p[x].val;
 63     for(int i=p[x].hd;i;i=e[i].lst)
 64     {
 65         int to=e[i].twd;
 66         if(to==f)
 67             continue;
 68         Add_dfs(to,x);
 69         p[x].Sum+=p[to].Sum;
 70     }
 71     V+=p[x].Sum*(w-p[x].Sum);
 72     return ;
 73 }
 74 int Emin(int x,int y)
 75 {
 76     return p[x].dp<p[y].dp?x:y;
 77 }
 78 int Lca(int x,int y)
 79 {
 80     x=p[x].eind;
 81     y=p[y].eind;
 82     if(x>y)
 83         std::swap(x,y);
 84     int l=lg[y-x+1];
 85     return Emin(eula[x][l],eula[y-(1<<l)+1][l]);
 86 }
 87 int Dis(int x,int y)
 88 {
 89     int z=Lca(x,y);
 90     return p[x].dp+p[y].dp-2*p[z].dp;
 91 }
 92 void grc_dfs(int x,int f)
 93 {
 94     p[x].wgt=1;
 95     int maxs=-1;
 96     for(int i=p[x].hd;i;i=e[i].lst)
 97     {
 98         int to=e[i].twd;
 99         if(to==f||p[to].vis)
100             continue;
101         grc_dfs(to,x);
102         p[x].wgt+=p[to].wgt;
103         if(maxs<p[to].wgt)
104             maxs=p[to].wgt;
105     }
106     maxs=std::max(maxs,size-p[x].wgt);
107     if(maxs<maxsize)
108     {
109         maxsize=maxs;
110         root=x;
111     }
112     return ;
113 }
114 void bin_dfs(int x,int f)
115 {
116     p[x].fa=f;
117     p[x].vis=true;
118     int tmp=size;
119     for(int i=p[x].hd;i;i=e[i].lst)
120     {
121         int to=e[i].twd;
122         if(p[to].vis)
123             continue;
124         root=0;
125         if(p[x].wgt<p[to].wgt)
126             size=tmp-p[x].wgt;
127         else
128             size=p[to].wgt;
129         maxsize=0x3f3f3f3f;
130         grc_dfs(to,to);
131         bin_dfs(root,x);
132     }
133     return ;
134 }
135 void update(int x,lnt y)
136 {
137     p[x].sum+=y;
138     for(int i=x;p[i].fa;i=p[i].fa)
139     {
140         lnt tmp=Dis(x,p[i].fa)*y;
141         p[i].disf+=tmp;
142         p[p[i].fa].diss+=tmp;
143         p[p[i].fa].sum+=y;
144     }
145     return ;
146 }
147 lnt Query(int x)
148 {
149     lnt ans=p[x].diss;
150     for(int i=x;p[i].fa;i=p[i].fa)
151     {
152         lnt tmp=Dis(x,p[i].fa);
153         ans+=p[p[i].fa].diss-p[i].disf;
154         ans+=tmp*(p[p[i].fa].sum-p[i].sum);
155     }
156     return ans;
157 }
158 int main()
159 {
160     scanf("%d%d",&n,&m);
161     for(int i=1;i<n;i++)
162     {
163         int a,b;
164         scanf("%d%d",&a,&b);
165         ade(a,b);
166         ade(b,a);
167     }
168     E_dfs(1,1);
169     for(int i=2;i<=dfn;i++)
170         lg[i]=lg[i>>1]+1;
171     for(int i=1;i<=20;i++)
172         for(int j=1;j+(1<<i)-1<=dfn;j++)
173             eula[j][i]=Emin(eula[j][i-1],eula[j+(1<<(i-1))][i-1]);
174     root=0;
175     size=n;
176     maxsize=0x3f3f3f3f;
177     grc_dfs(1,1);
178     rt=root;
179     bin_dfs(root,0);
180     for(int i=1;i<=n;i++)
181     {
182         scanf("%lld",&p[i].val);
183         update(i,p[i].val);
184         w+=p[i].val;
185     }
186     Add_dfs(1,1);
187     while(m--)
188     {
189         int cmd;
190         scanf("%d",&cmd);
191         if(cmd==1)
192         {
193             int x,y;
194             scanf("%d%d",&x,&y);
195             lnt dv=y-p[x].val;
196             update(x,dv);
197             V+=dv*Query(x);
198             w+=dv;
199             p[x].val=y;
200         }else{
201             int x;
202             scanf("%d",&x);
203             lnt ans=-V+w*w;
204             ans+=Query(x)*w;
205             printf("%lld\n",ans);
206         }
207     }
208     return 0;
209 }

转载于:https://www.cnblogs.com/blog-Dr-J/p/10160494.html

洛谷P3676 小清新数据结构题(动态点分治)相关推荐

  1. [luogu3676]小清新数据结构题

    前言 此题貌似有不少做法 题目相关 链接 题目大意 给出一棵无根树,支持两个操作 1.修改一个点的权值 2.指定一个点,计算以其为根时每个子树权值平方和 数据范围 n,q≤200000n,q\le20 ...

  2. [洛谷P3674]小清新人渣的本愿

    题目传送门 这道题是一道莫队题.对于每一种问法,就是查询对应的数是否在当前的区间内. 设$b[i]$表示莫队当前区间中有没有$i$这个数. 对于第一问"是否可以选出两个数它们的差为x&quo ...

  3. 洛谷 P3674 小清新人渣的本愿 [莫队 bitset]

    传送门 题意: 给你一个序列a,长度为n,有Q次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ...

  4. lp3676 小清新数据结构题

    传送门 Description 有一棵\(n\)个点的树,每个点有一个点权. 现在有\(q\)次操作,每次操作是修改一个点的点权或指定一个点,询问以这个点为根时每棵子树点权和的平方和. Solutio ...

  5. 洛谷 P3674 小清新人渣的本愿 bitset+莫队

    题目: https://www.luogu.org/problemnew/show/P3674 题目大意: 给你一个长度为 N N N的序列,每次询问[l,r]能不能取出两个数,和或差或积等于C&qu ...

  6. 洛谷 P3674 小清新人渣的本愿(莫队 +bitset)

    我们利用一个长度为 1e5 的 bitset,当数值 c 出现时,将 c 位置赋值为 1,对于题目要求的操作可以转变为 求 bitset 中存在两个位置相差为 x 的 1 这个比较难,如下图 bits ...

  7. 2017提高组D1T1 洛谷P3951 小凯的疑惑

    洛谷P3951 小凯的疑惑 原题 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的.现在小 凯想 ...

  8. 洛谷 P2186 小Z的栈函数

    洛谷 P2186 小Z的栈函数 题目 题目描述 小Z最近发现了一个神奇的机器,这个机器的所有操作都是通过维护一个栈来完成的,它支持如下11个操作: NUM X:栈顶放入X. POP:抛弃栈顶元素. I ...

  9. (最小割)洛谷P1361 小M的作物

    洛谷P1361 小M的作物 思路: 这是一个两者取一的模型,将点集一分为二. 最小割在数值上等同于最大流.割去权值和最小的边,使图分成两部分,割下来的边权值和为最小割. 对于此题,先不考虑种在一起的情 ...

最新文章

  1. 【Linux 应用编程】进程管理 - 进程间通信IPC之共享内存 mmap
  2. CISCO与华为3COM路由器配置差别
  3. 中国工业节能减排产业项目盈利模式及投资风险预警报告2021-2027年
  4. Android系统自带样式(@android:style/)
  5. 趣话题:git三部曲(二)-拆分历史提交记录reset
  6. 微信短内容要来了!新功能已开启内测申请
  7. 寄存器和立即数和内存单元
  8. Golang的协程调度
  9. 查询SQLServer的启动时间
  10. java中求1 2 =3,1. java dom编程艺术---杨涛、王建桥 -第3章 DOM(自总)
  11. Recommended System
  12. 零中频发射机设计与实现
  13. 职称计算机 将计算机broad_1下的e盘映射为k盘网络驱动器,职称计算机考试网络基础)试题及答案操作.doc...
  14. keil5代码可以下载但无法进行串口通信
  15. database is locked错误
  16. H3C网络故障排除方法
  17. 光耦w314的各引脚图_常用光耦型号代换大全
  18. delphi技巧总结收集
  19. java数据结构与算法基础(二)-排序
  20. iphone11看信号强度_iphone11信号强度真的会有提升吗

热门文章

  1. python如何快速登记凭证_如何高效地翻凭证?
  2. Reboot运维开发Python-03
  3. RHEL6_yum本地源配置
  4. 不联网的情况下,使用 electron-builder 快速打包全平台应用
  5. django mysql windows_Django+MySQL配置:Windows+Centos
  6. angular4获得焦点事件_深究AngularJS——如何获取input的焦点(自定义指令)
  7. SQL那些事儿(六)--数据库三大范式
  8. java argv_argv的编码是什么?
  9. 【java学习之路】(java SE篇)(练习)集合练习:经典例题
  10. Maven的性质与部署整理