传送门

解题思路

树上带修莫队,搞了两天。。终于开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. Windows mkdir

    创建目录. MKDIR [drive:]pathMD [drive:]path 如果命令扩展被启用,MKDIR 会如下改变: 如果需要,MKDIR 会在路径中创建中级目录.例如: 假设 \a 不存在, ...

  2. 跨域问题The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by t

    withCredentials 属性 上面说到,CORS请求默认不发送Cookie和HTTP认证信息.如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow- ...

  3. csp-s模拟测试89

    csp-s模拟测试89 $T1$想了一会儿没什么思路,一看$T2$  $1e18$当场自闭打完暴力就弃了,$T3$看完题感觉要求$lca$和$dep$,手玩了一下样例发现$lca$很显然,$dep$貌 ...

  4. JSON对象和字符串之间的相互转换 – JSON.parse() 和 JSON.stringify()

    所有现代浏览器都支持 JSON 对象,有两个非常有用的方法来处理 JSON 格式的内容: JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象 ...

  5. Android Support 包的作用、用法

    1, Android Support V4, V7, V13是什么?本质上就是三个java library. 2,  为什么要有support库?如果在低版本Android平台上开发一个应用程序,而应 ...

  6. Big Number HDU - 1212

    As we know, Big Number is always troublesome. But it's really important in our ACM. And today, your ...

  7. PHP面向对象魔术方法之__call函数

    l 基本介绍: (1) 当我们调了一个不可以访问的成员方法时,__call魔术方法就会被调用. (2) 不可以访问的成员方法的是指(1. 该成员方法不存在, 2. 成员方法是protected或者 p ...

  8. 使用Excel表格导入数据到Oracle表

    在工作中我们会遇到将通过数据手动录入到系统中的需求,如果数据量比较小,那么手动输入是可行的,倘若数据量很大,那么这些数据手动录入将会是一个很大的工作量,为了简化这个手动录入的操作流程,我们可以使用Ex ...

  9. How to use view controller containment

    https://www.hackingwithswift.com/example-code/uikit/how-to-use-view-controller-containment private f ...

  10. LeetCode 38.报数(Python3)

    题目: 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数.其前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 被读作  "one 1& ...