参考:http://blog.csdn.net/lych_cys/article/details/50845832

把树变成dfs括号序的形式,注意这个是不包含lca的(除非lca是两点中的一个)

然后把询问按照所属块一序,r二序,t三序排序(注意a和b数组的同名变量意思不一样),对于每个询问处理修改,时间正流或者逆流,修改答案时用vis数组记录这个位置是否在答案中被统计过来决定加减。对于修改序列的操作,如果他没有被统计在答案里就直接修改,否则修改答案。对lca特殊处理

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m,q,u[N],v[N],w[N],h[N],cnt,c[N],la[N],kuai,f[N],g[N],dfn,bl[N],cnta,cntb;
int de[N],fa[N],fr[N],si[N],hs[N],rl[N];
long long ans[N],sum;
bool vis[N];
struct qw
{
int ne,to;
}e[N<<1];
struct qwe
{
int l,r,t,rl;
}a[N],b[N];//对于b,l是位置,r是修改为的颜色,t是上一个颜色
bool cmp(qwe x,qwe y)
{
return bl[x.l]<bl[y.l]||bl[x.l]==bl[y.l]&&bl[x.r]<bl[y.r]||bl[x.l]==bl[y.l]&&bl[x.r]==bl[y.r]&&x.t<y.t;
}
int read()
{
int r=0;
char p=getchar();
while(p>'9'||p<'0')
p=getchar();
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r;
}
void add(int u,int v)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
h[u]=cnt;
}
void dfs1(int u,int fat)
{
fa[u]=fat;
de[u]=de[fat]+1;
si[u]=1;
f[u]=++dfn;
rl[dfn]=u;
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fat)
{
dfs1(e[i].to,u);
si[u]+=si[e[i].to];
if(si[e[i].to]>si[hs[u]])
hs[u]=e[i].to;
}
g[u]=++dfn;
rl[dfn]=u;
}
void dfs2(int u,int top)
{
fr[u]=top;
if(!hs[u])
return;
dfs2(hs[u],top);
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fa[u]&&e[i].to!=hs[u])
dfs2(e[i].to,e[i].to);
}
int lca(int u,int v)
{
for(;fr[u]!=fr[v];de[fr[u]]>de[fr[v]]?u=fa[fr[u]]:v=fa[fr[v]]);
return de[u]>de[v]?v:u;
}
void add(int x)
{
if(vis[x])
sum-=(long long)v[c[x]]*w[u[c[x]]--];
else
sum+=(long long)v[c[x]]*w[++u[c[x]]];
vis[x]^=1;
}
void change(int x,int y)
{
if(vis[x])
{
add(x);
c[x]=y;
add(x);
}
else
c[x]=y;
}
int main()
{
n=read(),m=read(),q=read();
for(int i=1;i<=m;i++)
v[i]=read();
for(int i=1;i<=n;i++)
w[i]=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
add(x,y);add(y,x);
}
for(int i=1;i<=n;i++)
c[i]=la[i]=read();
kuai=(int)pow(n,2.0/3);
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=dfn;i++)
bl[i]=(i-1)/kuai;
while(q--)
{
int t=read(),l=read(),r=read();
if(t==0)
{
b[++cntb].l=l;
b[cntb].t=la[l];
la[l]=b[cntb].r=r;
}
else
{
if(f[l]>f[r])
swap(l,r);
a[++cnta].r=f[r];
a[cnta].rl=cnta;
a[cnta].t=cntb;//cout<<lca(l,r)<<endl;
a[cnta].l=(lca(l,r)==l)?f[l]:g[l];
}
}
sort(a+1,a+cnta,cmp);
int l=1,r=0,t=1;
for(int i=1;i<=cnta;i++)
{
for(;t<=a[i].t;t++)
change(b[t].l,b[t].r);
for(;t>a[i].t;t--)
change(b[t].l,b[t].t);
while(l>a[i].l)
add(rl[--l]);
while(l<a[i].l)
add(rl[l++]);
while(r>a[i].r)
add(rl[r--]);
while(r<a[i].r)
add(rl[++r]);
int x=rl[l],y=rl[r],tmp=lca(x,y);//cout<<x<<" "<<y<<" "<<tmp<<endl;
if(x!=tmp&&y!=tmp)
{
add(tmp);
ans[a[i].rl]=sum;
add(tmp);
}
else
ans[a[i].rl]=sum;
}
for(int i=1;i<=cnta;i++)
printf("%lld\n",ans[i]);
return 0;
}
/*
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
*/

bzoj 3052: [wc2013]糖果公园【树上带修改莫队】的更多相关文章

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

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

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

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

  3. LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)

    传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...

  4. BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)

    题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...

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

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

  6. BZOJ 3052: [wc2013]糖果公园 | 树上莫队

    题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...

  7. [BZOJ4129]Haruna’s Breakfast(树上带修改莫队)

    BZOJ3585,BZOJ2120,BZOJ3757三合一. 对于树上路径问题,树链剖分难以处理的时候,就用树上带修改莫队. 这里的MEX问题,使用BZOJ3585的分块方法,平衡了时间复杂度. 剩下 ...

  8. bzoj 3052: [wc2013]糖果公园 带修改莫队

    3052: [wc2013]糖果公园 Time Limit: 250 Sec  Memory Limit: 512 MBSubmit: 506  Solved: 189[Submit][Status] ...

  9. 【Luogu P4074】[WC2013]糖果公园(树上带修改莫队)

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

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

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

随机推荐

  1. HDU 5521 Meeting【最短路】

    今天旁观了Angry_Newbie的模拟区域赛(2015shenyang) 倒着看最先看的M题,很明显的最短路问题,在我看懂的时候他们已经开始敲B了. 后来听说D过了很多人.. D题一看是个博弈,给了 ...

  2. git批量删除本地分支及远程分支

    1.批量删除本地分支 git branch |grep 'branchName' |xargs git branch -D git branch   查看本地分支 | grep 'branchName ...

  3. hdu6109(并查集+set/倍增)

    题目 http://acm.hdu.edu.cn/showproblem.php?pid=6109 分析 对于相同的条件,明显直接并查集 对于不同的条件,可以用set来保存,并查集合并的时候也要对se ...

  4. SpringDataRedis使用说明常用方法

    stringRedisTemplate.opsForValue().set("test", "100",60*10,TimeUnit.SECONDS);//向r ...

  5. 分享一个纯css制作的动画化,在网页(手机)载入等的时候能够引用!

    CSS代码例如以下: /* Custom Stylesheet */ body, html { margin: 0; -webkit-font-smoothing: antialiased; back ...

  6. Android之——监听手机开机事件

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47028535 本文中,主要通过监听开机广播来达到监听手机开机状态的操作.在Andr ...

  7. 【iOS9系列】-3DTouch开发

    [iOS9系列]-3DTouch开发 第一:简介 3DTouch 是iOS9系统系统下,在iPhone6s(iPhone6s Plus)手机上才能够使用的功能.熟练使用后,发现还是很便捷的. 但是模拟 ...

  8. 2016/05/13 Thinkphp 3.2.2 ①数据添加 ②收集表单数据入库操作 ③数据修改操作

    ①数据查询 add() 该方法返回被添加的新记录的主键id值 两种方式实现数据添加 数组方式数据添加 $goods = D(“Goods”); $arr = array(‘goods_name’=&g ...

  9. java8--NIO(java疯狂讲义3复习笔记)

    NIO采用内存映射文件的方式处理输入输出,NIO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了(这种方式模拟了操作系统上的虚拟内存的概念),通过这种方式来进行输入输出比传统的 ...

  10. iptraf 网卡 ip 端口 监控 netstat 关闭端口方法

    18 commands to monitor network bandwidth on Linux server – BinaryTides https://www.binarytides.com/l ...