luogu P4074 [WC2013]糖果公园
这种题显然要用树上莫队
何为树上莫队?就是在树上跑莫队算法就是先把树分块,然后把询问离线,按照左端点所在块为第一关键字,右端点所在块为第二关键字,时间戳(如果有修改操作)为第三关键字排序,然后依次处理.树上莫队要每个点记录是否访问,移动端点时需要把移动前和移动后的点之间的路径上的点(除了上述两点的lca)的访问状态取反,算答案时单独对询问两端点的lca算贡献
然后用莫队的那一套理论直接做就好了
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
using namespace std;
const int N=100000+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],tot=1;
il void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int n,m,q,szm,mm[N],nm,a[N],b[N],ti,mdf[N][3];
int fa[N],de[N],sz[N],son[N],top[N];
LL v[N],w[N],na,an[N];
int st[N],tp;
void dfs1(int x)
{
sz[x]=1;
int la=tp;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
if(sz[son[x]]<sz[y]) son[x]=y;
if(tp-la>=szm)
{
++nm;
while(tp!=la) mm[st[tp--]]=nm;
}
}
st[++tp]=x;
}
void dfs2(int x,int ntp)
{
top[x]=ntp;
if(son[x]) dfs2(son[x],ntp);
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
il int glca(int x,int y)
{
while(top[x]!=top[y])
{
if(de[top[x]]<de[top[y]]) swap(x,y);
x=fa[top[x]];
}
return de[x]<de[y]?x:y;
}
bool vis[N];
il void ad(int ww){++b[ww],na+=v[ww]*w[b[ww]];}
il void dl(int ww){na-=v[ww]*w[b[ww]],--b[ww];}
il void cg(int x)
{
if(vis[x]) dl(a[x]);
else ad(a[x]);
vis[x]^=1;
}
il void mv(int x,int y)
{
if(de[x]<de[y]) swap(x,y);
while(de[x]!=de[y]) cg(x),x=fa[x];
while(x!=y) cg(x),x=fa[x],cg(y),y=fa[y];
}
struct qu
{
int l,r,t,id;
bool operator < (const qu &bb) const {return mm[l]!=mm[bb.l]?mm[l]<mm[bb.l]:(mm[r]!=mm[bb.r]?mm[r]<mm[bb.r]:t<bb.t);}
}qq[N];
int main()
{
n=rd(),m=rd(),q=rd();
szm=(int)pow(n,0.61);
for(int i=1;i<=m;++i) v[i]=rd();
for(int i=1;i<=n;++i) w[i]=rd();
for(int i=1;i<n;++i) add(rd(),rd());
dfs1(1);
while(tp) mm[st[tp--]]=nm;
dfs2(1,1);
for(int i=1;i<=n;++i) a[i]=rd();
for(int i=1;i<=q;++i)
{
int op=rd(),x=rd(),y=rd();
if(op==1)
{
if(mm[x]>mm[y]) swap(x,y);
qq[i-ti].l=x,qq[i-ti].r=y,qq[i-ti].t=ti,qq[i-ti].id=i-ti;
}
else mdf[++ti][0]=x,mdf[ti][1]=y;
}
sort(qq+1,qq+q-ti+1);
for(int i=1,l=1,r=1,t=0;i<=q-ti;l=qq[i].l,r=qq[i].r,++i)
{
while(t<qq[i].t)
{
++t;
int xx=mdf[t][0],yy=mdf[t][1];mdf[t][2]=a[xx];
if(vis[xx]) dl(a[xx]),ad(yy);
a[xx]=yy;
}
while(t>qq[i].t)
{
int xx=mdf[t][0],yy=mdf[t][2];
if(vis[xx]) dl(a[xx]),ad(yy);
a[xx]=yy;
--t;
}
mv(l,qq[i].l),mv(r,qq[i].r);
int lca=glca(qq[i].l,qq[i].r);
cg(lca),an[qq[i].id]=na,cg(lca);
}
for(int i=1;i<=q-ti;++i) printf("%lld\n",an[i]);
return 0;
}
luogu P4074 [WC2013]糖果公园的更多相关文章
- BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)
题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...
- LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)
传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...
- 洛谷 P4074 [WC2013]糖果公园 解题报告
P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- Machine Learning Codeforces - 940F(带修莫队) && 洛谷P4074 [WC2013]糖果公园
以下内容未验证,有错请指正... 设块大小为T,则块数为$\frac{n}{T}$ 将询问分为$(\frac{n}{T})^2$块(按照左端点所在块和右端点所在块分块),同块内按时间从小到大依次处理 ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- [洛谷P4074][WC2013]糖果公园
题目大意:给一棵$n$个节点的树,每个点有一个值$C_i$,每次询问一条路径$x->y$,求$\sum\limits_{c}val_c\times \sum\limits_{i=1}^{cnt_ ...
- P4074 [WC2013]糖果公园
思路 带修莫队+树上莫队 注意代码细节即可,答案的维护非常简单 蒟蒻的大常数代码 #include <cstdio> #include <algorithm> #include ...
- bzoj 3052: [wc2013]糖果公园 带修改莫队
3052: [wc2013]糖果公园 Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 506 Solved: 189[Submit][Status] ...
随机推荐
- jmeter作用域规则
创建测试计划时,会创建一个有序的一系列将要被执行的请求列表,这些请求通常被组织在有序的控制器下 一些控制器会影响包含在它下面的请求顺序 ,这些特殊的控制器可以参考这里:the component re ...
- js 錯誤
try{ //需要被檢測是否拋出錯誤 } catch(err) { //錯誤處理代碼 } try.catch成對出現 throw:拋出錯誤 當錯誤發生時,javascript引擎停止運行,并生成一個錯 ...
- MySQL中条件放在where后面与放在on后面的区别
假设有两种表:test_on_position表和address表,address表存放地址,test_on_position存放会员及其常用的地址,数据如下: address表: test_on_p ...
- JS中var声明与function声明两种函数声明方式的区别
JS中常见的两种函数声明(statement)方式有这两种: // 函数表达式(function expression) var h = function() { // h } // 函数声明(fun ...
- Luogu5155 USACO18DEC Balance Beam(概率期望+凸包)
假设已经求出了在每个点的最优期望收益,显然最优策略是仅当移动一次后的期望收益>当前点收益时移动.对于初始点,其两边各存在一个最近的不满足上述条件的位置,因此从初始点开始随机游走,直到移动到这两个 ...
- Js 百分比进度条
[构想] CSS3 + JS CSS3控制进度 利用CSS3中的 @keyframes JS实现百分比 根据CSS来调整,时间 [页面代码] 第一种: 默认直接进入就是下载 CSS代码 body { ...
- MT【27】对数方程组求范围
解答:3 评论:此类题目通性通法为换元后化归为线性规划问题.当然不等式凑配也是常见技巧,只是容易范围扩大或者缩小.
- 【Gym - 101124A】The Baguette Master (数学,几何)
BUPT2017 wintertraining(15) #4F Gym - 101124A 题意 给定画框宽度,画的四边和一个对角线长度,求画框外沿周长. 题解 过顶点做画框的垂线,每个角都得到两个全 ...
- 2.9 C++使用默认参数的构造函数
总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ...
- 【转】19个必须知道的Visual Studio快捷键
本文将为大家列出在Visual Studio中常用的快捷键,正确熟练地使用快捷键,将大大提高你的编程工作效率. 项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt ...