传送门

解题思路

树上带修莫队,搞了两天。。终于开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. 【转载】99%的人都理解错了HTTP中GET与POST的区别

    作者:Larry链接:https://zhuanlan.zhihu.com/p/22536382来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 原文链接 作者:WebT ...

  2. web移动端rem的适配

    ** 需求: 随着移动端设备的变化,内容也跟着变化.**先来说说rem单位,以rem为单位,其大小是根据根元素(html标签)的字体大小来判断的,      如 html的font-size:100p ...

  3. C#实现拍照并且存水印照片

    由于一直在高校工作,就涉及到招生工作,招生时候又要收集学生图像采集,所以就随手写了一个图像采集工具,废话不多说,进入正题. 图像采集需要调用摄像头就行拍照操作,网上查了一下资料,需要引用以下3个dll ...

  4. 【转】5G标准——独立组网(SA)和非独立组网(NSA)

    独立组网模式(SA):指的是新建5G网络,包括新基站.回程链路以及核心网.SA引入了全新网元与接口的同时,还将大规模采用网络虚拟化.软件定义网络等新技术,并与5GNR结合,同时其协议开发.网络规划部署 ...

  5. Vue的组件及传参

    目录 Vue的组件及传参 Vue组件的概念 根组件 子组件(局部组件) 父组件向子组件传值 子组件向父组件传值 Vue的组件及传参 Vue组件的概念 我们首先要知道组件的概念,实际上每一个组件都是一个 ...

  6. vue组件间通信用例

    父组件传值给子组件 -- 以封装公用slide组件为例 父组件 <template> <section class="banner"> <slide ...

  7. 编程之法:面试和算法心得(寻找最小的k个数)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...

  8. netty 私有协议栈

    通信协议从广义上区分,可以分为公有协议和私有协议.由于私有协议的灵活性,它往往会在某个公司或者组织内部使用,按需定制,也因为如此,升级起来会非常方便,灵活性好.绝大多数的私有协议传输层都基于TCP/I ...

  9. Linux 实用指令(8)--网络配置

    目录 网络配置 1 Linux网络配置原理图(含虚拟机) 2 查看网络IP和网关 2.1 查询虚拟网络编辑器 2.2 修改IP地址(修改虚拟网络的IP) 2.3 查看网关 2.4 查看windows环 ...

  10. OpenGL键盘交互响应事件

    GLUT允许我们编写程序,在里面加入键盘输入控制,包括了普通键,和其他特殊键(如F1,UP).在这一章里我们将学习如何去检测哪个键被按下,可以从GLUT里得到些什么信息,和如何处理键盘输入.   处理 ...