不难发现,操作1可以看作如下操作:对于删去$a_{1},a_{2},...,a_{k}$后的每一个连通块(的点集)$V$,令$\forall x\in V,x$的收益加上$s$(其中$s=\sum_{x\in V}c_{x}$)

考虑建立类似于虚树的东西,即将每一个$a_{i}$连到第一个在$a_{i}$中的祖先,接下来遍历这棵新树(森林),对每一个节点枚举其在原树上的所有儿子,考虑该儿子的子树,分类讨论:

1.若这棵子树中没有$a_{i}$中的点,直接暴力修改(对dfs序维护线段树)

2.若这棵子树中有$a_{i}$中的点,找到还是其儿子的点(同时在其该子树中),将这些子树的dfs区间在整个区间中删掉,即将整个区间划分为若干段分别查询后求和并(分别)修改

关于如何建立前者的虚树,可以将所有节点子树对应的dfs区间排序后遍历一遍,或者也可以建立虚树之后再删除不在$a_{i}$中的点,时间复杂度均为$o(k\log n)$

但是,这样的操作次数(指对线段树)并不是$o(k)$,瓶颈是在于第1类(第2类虽然看似复杂但仔细分析不难发现其是$o(k)$的),考虑如何处理:

先树链剖分预处理,并找到所有第2类中的儿子和重儿子,用之前的方式处理(这里只有$o(k)$次),并在该节点上打一个修改标记,查询时$v$到根路径上根据重链顶端的父亲的标记对该重链顶端子树修改

(为了方便,可以将第2类中的轻儿子再减去子树和)

另外,还有一些细节问题:

1.需要去掉自己与自己贸易的情况,可以通过对这$a_{i}$个点的收益补上$c_{a_{i}}$,并再在操作2时将此时的答案额外减去$mc_{v}$即可(其中$m$为之前操作1的次数),显然这容易维护

2.如果1不在$a_{i}$中,实际上忽略了最外部的连通块(严格来说即包含1的连通块),可以通过建边$(0,1)$并将0强制加入$a_{i}$中解决(或特判)

综上,总复杂度为$o((q+\sum k)\log n)$,可以通过

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define ll long long
5 #define fi first
6 #define se second
7 #define L (k<<1)
8 #define R (L+1)
9 #define mid (l+r>>1)
10 struct Edge{
11 int nex,to;
12 }edge[N<<1];
13 int E,t,n,m,q,p,x,y,head[N],c[N],sz[N],mx[N],dep[N],fa[N][20],dfn[N],idfn[N],top[N],st[N],tag[N];
14 ll sum[N],f[N];
15 pair<int,int>a[N];
16 vector<int>v[N];
17 int lowbit(int k){
18 return (k&(-k));
19 }
20 ll get_sum(int k){
21 return sum[dfn[k]+sz[k]-1]-sum[dfn[k]-1];
22 }
23 void add(int x,int y){
24 edge[E].nex=head[x];
25 edge[E].to=y;
26 head[x]=E++;
27 }
28 int get_son(int x,int y){
29 for(int i=19;i>=0;i--)
30 if (dep[fa[x][i]]>dep[y])x=fa[x][i];
31 return x;
32 }
33 void dfs1(int k,int f,int s){
34 sz[k]=1,mx[k]=0,dep[k]=s,fa[k][0]=f;
35 for(int i=1;i<20;i++)fa[k][i]=fa[fa[k][i-1]][i-1];
36 for(int i=head[k];i!=-1;i=edge[i].nex)
37 if (edge[i].to!=f){
38 dfs1(edge[i].to,k,s+1);
39 sz[k]+=sz[edge[i].to];
40 if ((!mx[k])||(sz[mx[k]]<sz[edge[i].to]))mx[k]=edge[i].to;
41 }
42 }
43 void dfs2(int k,int f,int t){
44 dfn[k]=++dfn[0],idfn[dfn[0]]=k,top[k]=t;
45 if (mx[k])dfs2(mx[k],k,t);
46 for(int i=head[k];i!=-1;i=edge[i].nex)
47 if ((edge[i].to!=f)&&(edge[i].to!=mx[k]))dfs2(edge[i].to,k,edge[i].to);
48 }
49 void update(int k,ll x){
50 while (k<=n){
51 f[k]+=x;
52 k+=lowbit(k);
53 }
54 }
55 void update(int x,int y,ll z){
56 update(x,z);
57 if (y<n)update(y+1,-z);
58 }
59 void dfs(int k){
60 if (k)tag[k]++;
61 bool flag=0;
62 for(int i=0,j=0;i<v[k].size();i=j){
63 int son=get_son(v[k][i],k);
64 ll s=get_sum(son);
65 while ((j<v[k].size())&&(get_son(v[k][j],k)==son))s-=get_sum(v[k][j++]);
66 update(dfn[son],dfn[son]+sz[son]-1,s);
67 for(int t=i;t<j;t++)update(dfn[v[k][t]],dfn[v[k][t]]+sz[v[k][t]]-1,-s);
68 if (son==mx[k])flag=1;
69 else update(dfn[son],dfn[son]+sz[son]-1,-get_sum(son));
70 }
71 if ((!flag)&&(mx[k]))update(dfn[mx[k]],dfn[mx[k]]+sz[mx[k]]-1,get_sum(mx[k]));
72 for(int i=0;i<v[k].size();i++)dfs(v[k][i]);
73 v[k].clear();
74 }
75 ll query(int k){
76 ll ans=0;
77 for(int i=dfn[k];i;i-=lowbit(i))ans+=f[i];
78 ans-=(ll)m*c[k];
79 while (k){
80 ans+=tag[fa[top[k]][0]]*get_sum(top[k]);
81 k=fa[top[k]][0];
82 }
83 return ans;
84 }
85 int main(){
86 scanf("%d",&t);
87 while (t--){
88 scanf("%d%d",&n,&q);
89 E=m=dfn[0]=0;
90 memset(head,-1,sizeof(head));
91 memset(tag,0,sizeof(tag));
92 memset(f,0,sizeof(f));
93 for(int i=1;i<n;i++){
94 scanf("%d%d",&x,&y);
95 add(x,y),add(y,x);
96 }
97 dfs1(1,0,1),dfs2(1,0,1);
98 dfn[0]=mx[0]=1,sz[0]=n;
99 for(int i=1;i<=n;i++)scanf("%d",&c[i]);
100 for(int i=1;i<=n;i++)sum[i]=sum[i-1]+c[idfn[i]];
101 for(int i=1;i<=q;i++){
102 scanf("%d%d",&p,&x);
103 if (p==1){
104 m++;
105 for(int j=1;j<=x;j++){
106 scanf("%d",&y);
107 update(dfn[y],dfn[y],c[y]);
108 a[j]=make_pair(dfn[y],dfn[y]+sz[y]-1);
109 }
110 sort(a+1,a+x+1);
111 st[0]=0;
112 for(int j=1;j<=x;j++){
113 while ((st[0])&&(a[st[st[0]]].se<a[j].se))st[0]--;
114 v[idfn[a[st[st[0]]].fi]].push_back(idfn[a[j].fi]);
115 st[++st[0]]=j;
116 }
117 dfs(0);
118 }
119 if (p==2)printf("%lld\n",query(x));
120 }
121 }
122 return 0;
123 }

[hdu7076]ZYB's kingdom的更多相关文章

  1. 线段树 - ZYB's Premutation

    ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ...

  2. Constructing Roads In JGShining's Kingdom(HDU1025)(LCS序列的变行)

    Constructing Roads In JGShining's Kingdom  HDU1025 题目主要理解要用LCS进行求解! 并且一般的求法会超时!!要用二分!!! 最后蛋疼的是输出格式的注 ...

  3. 拓扑排序 --- hdu 4948 : Kingdom

    Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  4. codeforces 613D:Kingdom and its Cities

    Description Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. Ho ...

  5. Bestcoder round #65 && hdu 5593 ZYB's Tree 树形dp

    Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...

  6. Bestcoder round #65 && hdu 5592 ZYB's Premutation 线段树

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...

  7. HDU 4777 Rabbit Kingdom (2013杭州赛区1008题,预处理,树状数组)

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. [ACM] hdu 1025 Constructing Roads In JGShining's Kingdom (最长递增子序列,lower_bound使用)

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  9. Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 并查集求奇偶元环

    D. Dividing Kingdom II   Long time ago, there was a great kingdom and it was being ruled by The Grea ...

随机推荐

  1. Windows10系统下Java JDK下载、安装与环境变量配置(全网最全步骤)

    1.首先要明确: JDK.JRE.JVM的含义 2.下载目前最新的JDK:Java SE Development Kit 17,传送门::https://www.oracle.com/java/tec ...

  2. Azure Devops实践(5)- 构建springboot项目打包docker镜像及容器化部署

    使用Azure Devops构建java springboot项目,创建镜像并容器化部署 1.创建一个springboot项目,我用现有的项目 目录结构如下,使用provider项目 在根目录下添加D ...

  3. Android QMUI实战:沉浸式/适配状态栏

    近期研究QMUI换肤的实现,顺便分析了下QMUI的沉浸式. 网上已有很多关于QMUI实现页面沉浸式的文章,简而言之:复杂了. 本期,我们仅通过几行代码,即可完美实现页面沉浸式效果,并轻松匹配换肤的色彩 ...

  4. 返回值优化 RVO

    <深度探索C++对象模型>-- 2.3 返回值的初始化 & 在编译器层面做优化

  5. Go语言核心36讲(Go语言进阶技术三)--学习笔记

    09 | 字典的操作和约束 至今为止,我们讲过的集合类的高级数据类型都属于针对单一元素的容器. 它们或用连续存储,或用互存指针的方式收纳元素,这里的每个元素都代表了一个从属某一类型的独立值. 我们今天 ...

  6. 力扣 - 剑指 Offer 53 - I. 在排序数组中查找数字 I

    题目 剑指 Offer 53 - I. 在排序数组中查找数字 I 思路1 一般来说,首先想到的是使用一个变量,从头开始遍历整个数组,记录target数组出现的次数,但是这样的时间复杂度是O(n),还是 ...

  7. Coursera Deep Learning笔记 序列模型(三)Sequence models & Attention mechanism(序列模型和注意力机制)

    参考 1. 基础模型(Basic Model) Sequence to sequence模型(Seq2Seq) 从机器翻译到语音识别方面都有着广泛的应用. 举例: 该机器翻译问题,可以使用" ...

  8. 【BZOJ 1419】Red is good [概率DP]

    我 是 Z Z 概率好玄啊(好吧是我太弱.jpg Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻 ...

  9. Spring源码分析-BeanFactoryPostProcessor

    Spring源码分析-BeanFactoryPostProcessor 博主技术有限,本文难免有错误的地方,如果您发现了欢迎评论私信指出,谢谢 BeanFactoryPostProcessor接口是S ...

  10. 从零开始的DIY智能家居 - 基于 ESP32 的智能水浊度传感器

    前言 家里有个鱼缸养了几条鱼来玩玩,但是换水的问题着实头疼,经常一个不注意就忘记换水,鱼儿就没了.o(╥﹏╥)o 在获得 Spirit 1 边缘计算机 后就相当于有了一个人智能设备服务器,可以自己开发 ...