传送门

解题思路

树上带修莫队,搞了两天。。终于开O2+卡常大法贴边过了。。。bzoj上跑了183s。。其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点且两个点的LCA是这两个点的一个,那么树上的路径其实就是in[x]到in[y]。如果不是的话就是out[x]到in[y],且要加上lca,但这样太难统计,所以其实可以变成in[x]到in[y],然后直接特判。假如一段序列中既有一个点的in,又有一个点的out,那么其实就相当于没算,所以要记个vis数组表示这个东西该加还是该减,细节超级超级超级多。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map> using namespace std;
const int MAXN = ;
typedef long long LL; inline int rd(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
} inline void write(LL x){
if(x>) write(x/);
putchar(x%+'');
} int n,m,Q,v[MAXN],w[MAXN],tot,head[MAXN],bl[MAXN],Qnum;
int to[MAXN<<],nxt[MAXN<<],candy[MAXN],sizz,Qcnt,Ccnt;
int in[MAXN],out[MAXN],node[MAXN<<],num,cnt[MAXN];
int fa[MAXN],son[MAXN],siz[MAXN],dep[MAXN],top[MAXN];
LL ans[MAXN],Ans;
bool vis[MAXN];
map<pair<int,int>,int> mp; struct Data{
int l,r,id,pre,lca;
}q[MAXN]; struct Change{
int pos,val;
}c[MAXN]; inline void add(int bg,int ed){
to[++tot]=ed,nxt[tot]=head[bg],head[bg]=tot;
} void dfs1(int x,int f,int d){
fa[x]=f,dep[x]=d,siz[x]=;
in[x]=++num,node[num]=x;
register int maxson=-,u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
dfs1(u,x,d+);
siz[x]+=siz[u];
if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
}
out[x]=++num,node[num]=x;
} void dfs2(int x,int topf){
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);register int u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==son[x] || u==fa[x]) continue;
dfs2(u,u);
}
} inline int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>=dep[top[y]]) x=fa[top[x]];
else y=fa[top[y]];
}
return dep[x]>dep[y]?y:x;
} inline bool cmp(Data A,Data B){
if(bl[A.l]!=bl[B.l]) return bl[A.l]<bl[B.l];
if(bl[A.r]!=bl[B.r]) return bl[A.r]<bl[B.r];
return A.pre<B.pre;
} inline void Add(int x){
if(!vis[node[x]]){
vis[node[x]]^=;
cnt[candy[node[x]]]++;
Ans+=(LL)w[cnt[candy[node[x]]]]*v[candy[node[x]]];
// cout<<Ans<<endl;
}
else {
vis[node[x]]^=;
Ans-=(LL)w[cnt[candy[node[x]]]]*v[candy[node[x]]];
cnt[candy[node[x]]]--;
}
} inline void Work(int x){
if(vis[node[c[x].pos]]) {
Ans-=(LL)w[cnt[candy[node[c[x].pos]]]]*v[candy[node[c[x].pos]]];
cnt[candy[node[c[x].pos]]]--;cnt[c[x].val]++;
Ans+=(LL)w[cnt[c[x].val]]*v[c[x].val];
}
swap(c[x].val,candy[node[c[x].pos]]);
} int main(){
n=rd(),m=rd(),Q=rd();
for(register int i=;i<=m;i++) v[i]=rd();
for(register int i=;i<=n;i++) w[i]=rd();
register int x,y,opt;
for(register int i=;i<n;i++){
x=rd(),y=rd();
add(x,y),add(y,x);
}
for(register int i=;i<=n;i++) candy[i]=rd();
dfs1(,,);dfs2(,);register int Lca;
for(register int i=;i<=Q;i++){
opt=rd(),x=rd(),y=rd();
if(opt==){
if(mp.count(make_pair(x,y))) Lca=mp[make_pair(x,y)];
else {Lca=LCA(x,y);mp[make_pair(x,y)]=mp[make_pair(y,x)]=Lca;}
if(in[x]>in[y]) swap(x,y);
q[++Qcnt].l=in[x],q[Qcnt].r=in[y],q[Qcnt].id=Qcnt,q[Qcnt].pre=Ccnt,q[Qcnt].lca=in[Lca];
}
else {c[++Ccnt].pos=in[x];c[Ccnt].val=y;}
}
sizz=pow(n,Ccnt?0.6:0.5);
for(register int i=;i<=n;i++) bl[i]=i/sizz+;
// for(int i=1;i<=Qcnt;i++) cout<<q[i].l<<" "<<q[i].r<<endl;
sort(q+,q++Qcnt,cmp);
// for(int i=1;i<=Qcnt;i++) cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].id<<endl;
register int L=q[].l,R=q[].l-,now=;
for(register int i=;i<=Qcnt;i++){
while(L<q[i].l) {Add(L);L++;}
while(L>q[i].l) {L--;Add(L);}
while(R<q[i].r) {R++;Add(R);}
while(R>q[i].r) {Add(R);R--;}
while(now<q[i].pre) {now++;Work(now);}
while(now>q[i].pre) {Work(now);now--;}
if(q[i].lca!=q[i].l) Add(q[i].l);
if(q[i].lca!=q[i].l && q[i].lca!=q[i].r) Add(q[i].lca);
ans[q[i].id]=Ans;
if(q[i].lca!=q[i].l) Add(q[i].l);
if(q[i].lca!=q[i].l && q[i].lca!=q[i].r) Add(q[i].lca);
}
for(register int i=;i<=Qcnt;i++) write(ans[i]),puts("");
return ;
} /*
4 3 5
1 9 2
7 6 5 1
2 3
3 1
3 4
1 2 3 2
1 1 2
1 4 2
0 2 1
1 1 2
1 4 2 0 2 1
1 1 2
1 4 2
*/

LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)的更多相关文章

  1. luogu4074 [WC2013]糖果公园(树上带修莫队)

    link 题目大意:给一个树,树上每个点都有一种颜色,每个颜色都有一个收益 每次修改一个点上的颜色 或询问一条链上所有颜色第i次遇到颜色j可以获得w[i]*v[j]的价值,求链上价值和 题解:树上带修 ...

  2. 【BZOJ-3052】糖果公园 树上带修莫队算法

    3052: [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MBSubmit: 883  Solved: 419[Submit][Status] ...

  3. [WC2013][luogu4074] 糖果公园 [树上带修改莫队]

    题面: 传送门 思路: 一道实现起来细节比较恶心的题目 但是其实就是一个裸的树上带修改莫队 好像树上莫队也出不了什么结合题目,不像序列莫队天天结合AC自动机.后缀数组...... 莫队学习请戳这里:莫 ...

  4. BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)

    题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...

  5. BZOJ3052: [wc2013]糖果公园【树上带修莫队】

    Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 思路 非常模板的树上带修莫队 真的 ...

  6. BZOJ 4129 Haruna’s Breakfast ( 树上带修莫队 )

    题面 求树上某路径上最小的没出现过的权值,有单点修改 添加链接描述 分析 树上带修莫队板题,问题是怎么求最小的没出现过的权值. 因为只有nnn个点,所以没出现过的最小值一定在[0,n][0,n][0, ...

  7. bzoj4129 Haruna’s Breakfast 树上带修莫队+分块

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...

  8. BZOJ 3052 树上带修莫队

    思路: 就是把带修莫队移到了树上 块的大小开到(n^2/3)/2 比较好- 这是一个卡OJ好题 //By SiriusRen #include <cmath> #include <c ...

  9. P4074 [WC2013]糖果公园 树上莫队带修改

    题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...

随机推荐

  1. 树的直径+质因子——好题!cf1101D

    /* 因为质因子很少 状态转移时用dp[u][i]表示结点u的第i个质因子所在的最大深度即可 等价于带限制的求直径 */ #include<bits/stdc++.h> #include& ...

  2. kubernetes istio之gateway

    [root@master istio-]# kubectl apply -f samples/httpbin/httpbin.yaml service/httpbin created deployme ...

  3. ros多机系统

    编辑从机的~/.bashrc添加如下指令 方法一 export ROS_MASTER_URI=http://qian:11311 #qian是主机的机器名 export ROS_HOSTNAME=ro ...

  4. 关于Async与Await的FAQ

    =============C#.Net 篇目录============== 环境:VS2012(尽管System.Threading.Tasks在.net4.0就引入,在.net4.5中为其增加了更丰 ...

  5. Sublime Text 3,有了Anaconda就会如虎添翼

    作为Python开发环境的Sublime Text 3,有了Anaconda就会如虎添翼.Anaconda是目前最流行也是最有威力的Python代码提示插件. 操作步骤 1.打开package con ...

  6. 有道云笔记新功能发现——有道云笔记剪报,完美解决不开会员保存csdn博客到本地的问题。

    怎么用 方法一:谷歌插件 方法二:http://note.youdao.com/web-clipper-chrome.html 添加到书签 功能: 能够把网页浏览的内容保存到有道云笔记 解决了自己的难 ...

  7. re.groups取出来的空元祖??

    源自学习笔记: day23_1_re_ groups方法取出来的字符是空的元组??为啥? ''' # ------------------------------------------------- ...

  8. WannaCry结束了? 安专家注册域名掐断病毒传播

    腾讯科技讯,(韩依民) 5 月 13 日,席卷全球的勒索病毒 WannaCry(也被称作 WanaCrypt 或 WCry),在今日晚间被互联网安全人员找到阻止其传播的方法. 据北京云纵信息技术有限公 ...

  9. node环境下安装vue-cli

    一. node安装 1)如果不确定自己是否安装了node,可以在命令行工具内执行: node -v  (检查一下 版本): 2)如果 执行结果显示: xx 不是内部命令,说明你还没有安装node , ...

  10. assert(断言)

    Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常. 语法格式: assert expression 等价于: if not expression: ra ...