【题目链接】

http://uoj.ac/problem/58

【题意】

有一棵树,结点有自己的颜色,若干询问: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】糖果公园(树上莫队算法+修改操作)的更多相关文章

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

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

  2. P4074 [WC2013]糖果公园 树上莫队带修改

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

  3. 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 ...

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

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

  5. [BZOJ3052][UOJ#58][WC2013]糖果公园

    [BZOJ3052][UOJ#58][WC2013]糖果公园 试题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来 ...

  6. 【WC2013】 糖果公园 - 树上莫队

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

  7. 【WC2013】糖果公园 [树上莫队]

    题意: 一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和 sro VFK 树上莫队 按照王室联邦的方法分块,块的大小直径个数有保证,并不 ...

  8. BZOJ3052/UOJ#58 [wc2013]糖果公园 莫队 带修莫队 树上莫队

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3052.html 题目传送门 - BZOJ3052 题目传送门 - UOJ#58 题意 给定一棵树,有 ...

  9. 洛谷P4074 [WC2013]糖果公园(莫队)

    传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...

随机推荐

  1. /dev/tty /dev/ttyS0 /dev/tty0,/dev/null区别

    1./dev/tty表示控制终端如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty就是当前进程的控制终端的设备特殊文件.可以使用命令”ps –ax”来查看进程 ...

  2. 用Spring Data JPA 基于内存存储pojo的简单案例

    poject结构如下: Customer.java类是一个pojo类,代码如下: package hello; import javax.persistence.Entity; import java ...

  3. [转]c/c++输入函数

    最全输入函数 c/c++ 一: c=getchar(); 功能:读入一个字符 说明:调用此函数时要求在程序的第一行有预编译命令:#include<stdio>,不过在做c++时 有#inc ...

  4. synergy在Windows和ubuntu 多台PC共享一套键盘鼠标

    UBUNTU 服务端安装: sudo apt-get install quicksynergy window 客户端安装: http://www.9ht.com/xz/68108.html#addre ...

  5. 一、导入、导出远程Oracle数据库

    一.导入.导出远程Oracle数据库  其语法实示例如下:    imp/exp [username[/password[@service]]]   其中service是服务实例名,关于如何创建服务实 ...

  6. oracle数据库导入导出命令!

    Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢 ...

  7. C# Winform DataGridView分页功能的实现

    // 1.定义几个所需的公有成员: ; //每页显示行数 ; //总记录数 ; //页数=总记录数/每页显示行数 ; //当前页号 ; //当前记录行 DataSet ds = new DataSet ...

  8. mongodb用户授权

    1)登录admin 数据库,admin是隐藏的数据库,为mongodb的超级管理员数据表mongo admin新建用户db.createUser({'user':'test','pwd':'12345 ...

  9. WEBUS2.0 In Action - [源代码] - C#代码搜索器

    最近由于工作的需要, 要分析大量C#代码, 在数万个cs文件中搜索特定关键词. 这是一项非常耗时的工作, 用Notepad++要运行接近半个小时. 于是我利用WEBUS2.0 SDK创建了一个代码搜索 ...

  10. 旧书重温:0day2【1】 简单的缓冲区溢出案例

    0x01 准备: VMwarePlayer (我是在360软件管家那搜到的下载的) xp sp2 http://user.qzone.qq.com/252738331/blog/1357138598 ...