洛谷P4074 [WC2013]糖果公园(莫队)
传送门
总算会树形莫队了……
上次听说树形莫队是给树分块,实在看不懂。然后用括号序列的方法做总算能弄明白了
先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下
拿样例为例,它的括号序列就是$12443321$
那么我们扩展区间对答案的贡献是可以$O(1)$计算的
假设扩展出的点的颜色是$c$,那么变化量为$val_c*worth_{cnt_c+1}$
因为括号序列它在扩展的时候会把子树里的扫两遍,那么就可以把子树中的答案去掉了
怎么去掉呢?记录一个$vis$然后每次扫到的时候异或一下,看看是否被扫过就行了
然而有几个问题
第一,$LCA$不是路径端点的话不会被记入答案
考虑上面的括号序列,如果要从$4$到$3$那么$2$是不会被计入答案的
第二,起点不是$LCA$的话不会被记入答案
考虑上面,$u$被算了两次,刚好把自己给减掉了
所以上面的两种情况要特判
然后因为是带修莫队,所以再加上时间这一维
还有这题细节挺多的……我因为跳时间轴的时候一个地方写错WA了好久……
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstring> 6 #include<cmath> 7 #define ll long long 8 using namespace std; 9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 10 char buf[1<<21],*p1=buf,*p2=buf; 11 inline int read(){ 12 #define num ch-'0' 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch=='-')&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 char sr[1<<21],z[30];int C=-1,Z; 22 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 23 inline void print(ll x){ 24 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 25 while(z[++Z]=x%10+48,x/=10); 26 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 27 } 28 const int N=100005; 29 struct query{ 30 int x,y,l,r,id,t; 31 }q[N];int q1; 32 struct change{int x,c;}t[N];int q2; 33 int n,m,L,R,T,s,Q;ll now,ans[N]; 34 int ver[N<<1],edge[N<<1],head[N],Next[N<<1],top[N],dfn[N],dep[N],sz[N],son[N],lis[N<<1],fa[N],tot,num; 35 int vis[N],col[N],wor[N],cnt[N],val[N]; 36 inline bool cmp(const query a,const query b){ 37 if(a.l^b.l) return a.l<b.l; 38 if(a.r^b.r) return a.l&1?a.r<b.r:a.r>b.r; 39 return (a.l^a.r)&1?a.t<b.t:a.t>b.t; 40 } 41 inline void add(int u,int v){ 42 ver[++tot]=v,Next[tot]=head[u],head[u]=tot; 43 ver[++tot]=u,Next[tot]=head[v],head[v]=tot; 44 } 45 void dfs(int u){ 46 dep[u]=dep[fa[u]]+1,sz[u]=1; 47 for(int i=head[u];i;i=Next[i]){ 48 int v=ver[i]; 49 if(v!=fa[u]){ 50 fa[v]=u,dfs(v),sz[u]+=sz[v]; 51 if(sz[v]>sz[son[u]]) son[u]=v; 52 } 53 } 54 } 55 void dfs(int u,int t){ 56 top[u]=t,lis[dfn[u]=++num]=u; 57 if(son[u]) dfs(son[u],t); 58 for(int i=head[u];i;i=Next[i]){ 59 if(ver[i]!=fa[u]&&ver[i]!=son[u]) dfs(ver[i],ver[i]); 60 } 61 lis[++num]=u; 62 } 63 inline int LCA(int u,int v){ 64 while(top[u]!=top[v]){ 65 if(dep[top[u]]<dep[top[v]]) swap(u,v); 66 u=fa[top[u]]; 67 } 68 return dep[u]<dep[v]?u:v; 69 } 70 inline void sol(int x){ 71 int c=col[x]; 72 (vis[x]^=1)?now+=(ll)wor[++cnt[c]]*val[c]:now-=(ll)wor[cnt[c]--]*val[c]; 73 } 74 inline void mdy(int i){ 75 int u=t[i].x,x=t[i].c,y=col[u]; 76 if(vis[u]) now+=(ll)wor[++cnt[x]]*val[x]-(ll)wor[cnt[y]--]*val[y]; 77 t[i].c=y,col[u]=x; 78 } 79 int main(){ 80 n=read(),m=read(),Q=read(); 81 for(int i=1;i<=m;++i) val[i]=read(); 82 for(int i=1;i<=n;++i) wor[i]=read(); 83 for(int i=1;i<n;++i){ 84 int u=read(),v=read();add(u,v); 85 } 86 for(int i=1;i<=n;++i) col[i]=read(); 87 dfs(1),dfs(1,1); 88 while(Q--){ 89 int opt=read(),x=read(),y=read(); 90 if(opt){if(dfn[x]>dfn[y]) swap(x,y); 91 q[++q1]=(query){x,y,dfn[x],dfn[y],q1,q2}; 92 } 93 else t[++q2]=(change){x,y}; 94 } 95 s=pow(n,q2?2.0/3:1.0/2); 96 for(int i=1;i<=n;++i) q[i].l/=s,q[i].r/=s; 97 sort(q+1,q+1+q1,cmp),L=dfn[q[1].l],R=L-1,T=0; 98 for(int i=1;i<=q1;++i){ 99 int u=q[i].x,v=q[i].y; 100 int l=dfn[u],r=dfn[v],g=q[i].t; 101 while(L>l) sol(lis[--L]); 102 while(R<r) sol(lis[++R]); 103 while(L<l) sol(lis[L++]); 104 while(R>r) sol(lis[R--]); 105 while(T<g) mdy(++T); 106 while(T>g) mdy(T--); 107 //LCA不是路径端点的话是不会计算的 108 //出发点u如果不是LCA也是不会计算的 109 //这两个都要特判 110 int p=LCA(u,v); 111 if(u!=p){sol(u);if(v!=p) sol(p);} 112 ans[q[i].id]=now; 113 if(u!=p){sol(u);if(v!=p) sol(p);} 114 } 115 for(int i=1;i<=q1;++i) print(ans[i]); 116 Ot(); 117 return 0; 118 }
转载于:https://www.cnblogs.com/bztMinamoto/p/9537637.html
洛谷P4074 [WC2013]糖果公园(莫队)相关推荐
- YBTOJ洛谷P4074:糖果公园(树上莫队)
文章目录 解析 update: 代码 所谓树上莫队,就是在树上的莫队 (逃) 传送门 解析 似乎就是树上的这道题 考虑如何转化为序列问题呢? 考虑dfs序 但是又一个问题... 似乎这条链的dfs序不 ...
- LG P4074 [WC2013] 糖果公园(带修莫队,树上莫队)
LG P4074 [WC2013] 糖果公园 Solution 树上带修莫队,主要还是复习带修莫队和树上莫队. 带修莫队: 带修莫队要先对lll分块的序号作为第一关键字,对rrr分块的序号作为第二关键 ...
- 洛谷P3245 [HNOI2016]大数 【莫队】
题目 题解 除了\(5\)和\(2\) 后缀数字对\(P\)取模意义下,两个位置相减如果为\(0\),那么对应子串即为\(P\)的倍数 只用对区间种相同数个数\(x\)贡献\({x \choose 2 ...
- 洛谷P5071 [YNOI2015]此时此刻的光辉 莫队+玄学优化+卡常QWQ
题目链接:传送门 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此 ...
- 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法
[题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- 洛谷3953:逛公园——题解
https://www.luogu.org/problemnew/show/P3953 策策同学特别喜欢逛公园.公园可以看成一张n个点m条边构成的有向图,且没有自环和重边.其中1号点是公园的入口,n号 ...
- [WC2013]糖果公园
Description 题库链接 给你一棵 $n$ 个节点,有 $m$种颜色的树.每个节点上有一个颜色.定义一条树上路径的价值为 $sum_c V_c(\sum_{i=1}^{tim_c}W_i)$ ...
- 洛谷P3275 [SCOI2011]糖果
题目描述 幼儿园里有\(N\)个小朋友,\(lxhgww\)老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他 ...
- 洛谷P4513 小白逛公园
区间最大子段和模板题.. 维护四个数组:prefix, suffix, sum, tree 假设当前访问节点为cur prefix[cur]=max(prefix[lson],sum[lson]+pr ...
最新文章
- angular react_Angular 2 vs React:将会有鲜血
- μC/OS-II软件定时器的分析与测试
- Python-GUI编程PyQT5案例:注册界面扇形菜单动画及相关事件处理
- Codeforces Round #712 (Div. 2)
- 从位图数据取得位图句柄
- LeetCode 141 Linked List Cycle
- java项目中build path的设置
- 2022年计算机软件水平考试信息处理技术员练习题及答案
- Hybird app开发入门之Native和H5页面交互原理
- VMware Fusion for Apple silicon
- 自制太阳能手机充电器
- mysql80004005错误_常见的80004005错误及其解决方法
- 软件测试人员面试技巧总结
- 服务价值 100 万亿美元的行业,是时候收购市场领导者英伟达了
- 2022 年 8 种云计算趋势:超支、安全和工作负载
- 关于树莓派4B安装桌面控件wbar和conky解决报错的一种方案
- 农夫过河(基于C语言)
- 计算机识别技术检测交通标志,基于计算机视觉的交通标志检测与识别算法研究...
- 多表联合查询、嵌套查询
- 菲律宾的光伏市场只有一个字概况:穷