uoj #58. 【WC2013】糖果公园(树上莫队算法+修改操作)
【题目链接】
【题意】
有一棵树,结点有自己的颜色,若干询问:u,v路径上的获益,并提供修改颜色的操作。
其中获益定义为Vc*W1+Vc*W2+…+Vc*Wcnt,cnt为经过颜色c的次数。
【思路】
如果没有修改操作就和 苹果树 这道题一样了。
加上修改操作,我们可以对每一个修改操作打上一个时间戳,并记录每一个查询最后修改的时间戳。这样在莫队“区间移动”的时候,只需要根据时间戳进行时光逆流或顺流,即加上现在时间内前一个时间没有的修改或消除现在时间内没有前一个时间存在的修改。
对于一个修改,如果已经打上标记即这时候计入了now,我们应该先把它在路径上取反存在性,修改后再取反一下就又以新的权值回到了路上,就是重新计算一下贡献。
【代码】
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 3e5+;
const int D = ; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge { int v,nxt;
}e[N<<];
int en=,front[N];
void adde(int u,int v)
{
e[++en]=(Edge){v,front[u]}; front[u]=en;
} int n,m,B,Q,dfsc,top,Bcnt;
int cnt[N],C[N]; ll now,ans[N],W[N],V[N];
int pos[N],dfn[N],dep[N],fa[N][D],vis[N],st[N],pre[N]; struct Node
{
int id,u,v,t;
bool operator < (const Node& rhs) const
{
if(pos[u]==pos[rhs.u]&&pos[v]==pos[rhs.v]) return t<rhs.t;
else if(pos[u]==pos[rhs.u]) return pos[v]<pos[rhs.v];
else return pos[u]<pos[rhs.u];
}
} q[N];
struct opNode { int u,v,pre;
} que[N]; int qs,cs; int dfs(int u)
{
FOR(i,,D-)
fa[u][i]=fa[fa[u][i-]][i-];
dfn[u]=++dfsc;
int siz=;
trav(u,i) {
int v=e[i].v;
if(v!=fa[u][]) {
fa[v][]=u;
dep[v]=dep[u]+;
siz+=dfs(v);
if(siz>=B) {
Bcnt++;
while(siz--)
pos[st[top--]]=Bcnt;
}
}
}
st[++top]=u;
return siz+;
}
int lca(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);
int t=dep[u]-dep[v];
FOR(i,,D-)
if(t&(<<i)) u=fa[u][i];
if(u==v) return u;
for(int i=D-;i>=;i--)
if(fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
return fa[u][];
}
void Xor(int u)
{
if(vis[u])
vis[u]=,now-=V[C[u]]*W[cnt[C[u]]--];
else
vis[u]=,now+=V[C[u]]*W[++cnt[C[u]]];
}
void upd(int u,int v)
{
if(vis[u]) {
Xor(u); C[u]=v; Xor(u);
}
else
C[u]=v;
}
void work(int u,int v)
{
while(u!=v) {
if(dep[u]<dep[v]) swap(u,v);
Xor(u); u=fa[u][];
}
} int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
n=read(),m=read(),Q=read();
B=pow(n,2.0/)*0.5;
FOR(i,,m) V[i]=read();
FOR(i,,n) W[i]=read();
int op,u,v,w;
FOR(i,,n-) {
u=read(),v=read();
adde(u,v),adde(v,u);
}
FOR(i,,n)
pre[i]=C[i]=read(); dfs();
++Bcnt;
while(top) pos[st[top--]]=Bcnt;
FOR(i,,Q)
{
op=read(),u=read(),v=read();
if(op==) {
++cs;
que[cs].u=u,que[cs].v=v;
que[cs].pre=pre[u]; pre[u]=v;
} else {
++qs;
if(dfn[u]>dfn[v]) swap(u,v);
q[qs].u=u,q[qs].v=v;
q[qs].id=qs; q[qs].t=cs;
}
}
sort(q+,q+qs+);
FOR(i,,q[].t) upd(que[i].u,que[i].v);
work(q[].u,q[].v);
int lc=lca(q[].u,q[].v);
Xor(lc);
ans[q[].id]=now;
Xor(lc);
FOR(i,,qs)
{
for(int j=q[i-].t+;j<=q[i].t;j++) upd(que[j].u,que[j].v);
for(int j=q[i-].t;j>q[i].t;j--) upd(que[j].u,que[j].pre);
work(q[i-].u,q[i].u);
work(q[i-].v,q[i].v);
int lc=lca(q[i].u,q[i].v);
Xor(lc);
ans[q[i].id]=now;
Xor(lc);
}
FOR(i,,qs) printf("%lld\n",ans[i]);
return ;
}
P.S.辣鸡错误毁我青春(摔
说到底还是自己太辣鸡了QAQ
uoj #58. 【WC2013】糖果公园(树上莫队算法+修改操作)的更多相关文章
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- BZOJ3052:[WC2013]糖果公园(树上莫队)
Description Input Output Sample Input 4 3 51 9 27 6 5 12 33 13 41 2 3 21 1 21 4 20 2 11 1 21 4 2 Sam ...
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...
- [BZOJ3052][UOJ#58][WC2013]糖果公园
[BZOJ3052][UOJ#58][WC2013]糖果公园 试题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来 ...
- 【WC2013】 糖果公园 - 树上莫队
问题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩.糖果公园的结构十分奇特,它由 n 个游览点构成, ...
- 【WC2013】糖果公园 [树上莫队]
题意: 一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和 sro VFK 树上莫队 按照王室联邦的方法分块,块的大小直径个数有保证,并不 ...
- BZOJ3052/UOJ#58 [wc2013]糖果公园 莫队 带修莫队 树上莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3052.html 题目传送门 - BZOJ3052 题目传送门 - UOJ#58 题意 给定一棵树,有 ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
随机推荐
- 一个n位的数,去掉其中的k位,问怎样去使得留下来的(n-k)位数按原来的前后顺序组成的数最小
例如 8314925去掉4个数,留下125最小,注意有前后顺序要求,要是没有顺序当然是123. 解决方案 贪心算法,在每次被访问的位置保证有最优解. 思路一 分析:求一共n位,求其中的m位组成的数最小 ...
- mysql命令分类(DML、DDL、DCL)
DML:数据操作语言(操作数据) SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数 ...
- 易犯的PHP小错误及相应分析
变量声明如果在一条语句中声明一个变量,如下所示:$var = 'value'; 编译器首先会求出语句右半部分的值,恰恰正是语句的这一部分常常会引发错误.如果使用的语法不正确,就会出现解析错误. 解析错 ...
- 分析和解析PHP代码的7大工具
PHP已成为时下最热门的编程语言之一,然而却有许多PHP程序员苦恼找不到合适的工具来帮助自己分析和解析PHP代码.今天小编就为大家介绍几个非常不错的工具,来帮助程序员们提高自己的工作效率,一起来看看吧 ...
- centos 升级GCC/G++
#get rep yum install centos-release-scl-rh #yum install centos-release-scl # install g++ 5.2.1 yum - ...
- poj-3616 Milking Time (区间dp)
http://poj.org/problem?id=3616 bessie是一头工作很努力的奶牛,她很关心自己的产奶量,所以在她安排接下来的n个小时以尽可能提高自己的产奶量. 现在有m个产奶时间,每个 ...
- DBContext
http://www.entityframeworktutorial.net/EntityFramework4.3/dbcontext-vs-objectcontext.aspx As you hav ...
- Cookie操作类 实现记住用户名和密码的功能
import java.util.Hashtable;import java.util.Iterator;import java.util.Set;import javax.servlet.http. ...
- CodeIgniter的缓存设置
数据库缓存 数据库缓存类允许你把数据库查询结果保存在文本文件中以减少数据库访问. 激活缓存需要三步: 在服务器上创建一个可写的目录以便保存缓存文件. 在文件 application/config/da ...
- Azure PowerShell 1.0.0以上版本在中国Azure使用的注意事项
随着Azure PowerShell 1.0.0+的推出,越来越多的客户开始使用新的版本的Azure PowerShell.此版本的PowerShell最大的改变在于将原先的Switch-AzureM ...