【WC2013】糖果公园 [树上莫队]
题意:
一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和
树上莫队
按照王室联邦的方法分块,块的大小直径个数有保证,并不需要连通
和带修改莫队一样按照$(pos[u],pos[v],tim)$排序
维护$u,v,cur$三个点,以及每个节点的访问状态$vis[]$,每种颜色出现次数$cou[]$,当前答案$now$
如何移动?
时间移动和序列上一样
$u,v$移动到$u,v'$
$Path(u,v)=Path(u,root) \oplus Path(v,root) \oplus lca(u,v)$
先不管$lca$,令$T(u,v)=Path(u,root) \oplus Path(v,root)$
$T(u,v')=Path(u,root) \oplus Path(v',root)$
经计算$T(u,v')=T(u,v) \oplus T(v,v')$
画一下图很好理解
所以移动的时候我们只要更新$v$到$v'$路径上除去$lca$的所有点就可以了,最后对于每个询问额外把$lca(u,v)$加上
分块大小貌似稍小一点比较好
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,k,Q,a[N],t[N],op,x,y, val[N];
ll w[N]; struct edge{int v,ne;} e[N<<];
int cnt,h[N];
inline void ins(int u,int v){
e[++cnt]=(edge){v,h[u]}; h[u]=cnt;
e[++cnt]=(edge){u,h[v]}; h[v]=cnt;
}
int block,m,pos[N];
int st[N],top;
void dfs(int u,int fa){
int bot=top;
for(int i=h[u];i;i=e[i].ne) if(e[i].v!=fa){
dfs(e[i].v, u);
if(top-bot>=block){
m++;
while(top!=bot) pos[st[top--]]=m;
}
}
st[++top]=u;
} int fa[N][], deep[N];
void dfs(int u){
for(int i=; (<<i)<=deep[u]; i++)
fa[u][i]=fa[ fa[u][i-] ][i-];
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa[u][]){
deep[ e[i].v ]=deep[u]+;
fa[ e[i].v ][]=u;
dfs(e[i].v);
}
}
inline int lca(int x,int y){
if(deep[x]<deep[y]) swap(x, y);
int bin=deep[x]-deep[y];
for(int i=;i<;i++) if((<<i)&bin) x=fa[x][i];
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i]) x=fa[x][i], y=fa[y][i];
return x==y ? x : fa[x][];
} struct cmeow{int u,next,last;} cq[N];
struct meow{
int u,v,tim,id;
bool operator <(const meow &a) const {
return pos[u]==pos[a.u] ? (pos[v]==pos[a.v] ? tim<a.tim : pos[v]<pos[a.v]) : pos[u]<pos[a.u];
}
}q[N];
int p,tim,u,v,cur; ll now,ans[N];
int vis[N], cou[N];
inline void cha(int u,int d){
int &c=a[u];
if(vis[u]){
now-= w[cou[c]] * val[c]; now-= w[cou[d]] * val[d];
cou[c]--; cou[d]++;
now+= w[cou[c]] * val[c]; now+= w[cou[d]] * val[d];
}
c=d;
}
inline void Xor(int u){
int c=a[u];
now-= w[cou[c]] * val[c];
vis[u] ? cou[c]-- : cou[c]++; vis[u]^=;
now+= w[cou[c]] * val[c];
}
void move(int x,int y){
if(deep[x]<deep[y]) swap(x, y);
while(deep[x]>deep[y]) Xor(x), x=fa[x][];// printf("%d %lld\n",x,now);
while(x!=y) Xor(x), Xor(y), x=fa[x][], y=fa[y][];
}
void modui(){
u=; v=;
for(int i=;i<=p;i++){
while(cur<q[i].tim) cur++, cha(cq[cur].u, cq[cur].next);
while(cur>q[i].tim) cha(cq[cur].u, cq[cur].last), cur--;
if(u!=q[i].u) move(u, q[i].u), u=q[i].u;
if(v!=q[i].v) move(v, q[i].v), v=q[i].v; int anc=lca(u, v);
Xor(anc); ans[q[i].id]= now; Xor(anc);
}
}
int main(){
freopen("in","r",stdin);
n=read(); k=read(); Q=read();
for(int i=;i<=k;i++) val[i]=read();
for(int i=;i<=n;i++) w[i]=read()+w[i-];
for(int i=;i<n ;i++) ins(read(), read() );
for(int i=;i<=n;i++) a[i]=t[i]=read(); block=pow(n,(double)1.9/);
dfs(, );
while(top) pos[st[top--]]=m;
dfs(); for(int i=;i<=Q;i++){
op=read(); x=read(); y=read();
if(op) p++,q[p]=(meow){x,y,tim,p};
else tim++,cq[tim]=(cmeow){x,y,t[x]}, t[x]=y;
}
sort(q+, q++p);
modui();
for(int i=;i<=p;i++) printf("%lld\n", ans[i]);
}
【WC2013】糖果公园 [树上莫队]的更多相关文章
- 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 ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...
- 【WC2013】 糖果公园 - 树上莫队
问题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩.糖果公园的结构十分奇特,它由 n 个游览点构成, ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)
传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...
- luogu4074 [WC2013]糖果公园(树上带修莫队)
link 题目大意:给一个树,树上每个点都有一种颜色,每个颜色都有一个收益 每次修改一个点上的颜色 或询问一条链上所有颜色第i次遇到颜色j可以获得w[i]*v[j]的价值,求链上价值和 题解:树上带修 ...
- 【BZOJ3052】【UOJ#58】【WC2013】糖果公园(树上莫队)
[BZOJ3052][UOJ#58][WC2013]糖果公园(树上莫队) 题面 UOJ 洛谷 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引 ...
随机推荐
- Cup(二分)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2289 hdu_2289:Cup Time Limit: 3000/1000 MS (Java/Othe ...
- 解决JSONObject.fromObject数字为null时被转换为0
在使用JSONObject.fromObject的时候会遇到一种情况就是当对象的某一个Double型或Integer型的属性为空的时候,转JSON的时候会变成0.当一个布尔型的属性为空的时候,转JSO ...
- Java应用开发中的字符集与字符编码
事出有因 在向HttpURLConnection的输出流写入内容时,因没有设置charset,导致接收方对数据的验签不一致. URL url = new URL(requestUrl); //打开连接 ...
- sql中查询同一列所有值出现的次数
尊重原创:http://blog.csdn.net/love_java_cc/article/details/52234889 有表如下table3: 需要查询country中各个国家出现的次数 SQ ...
- MLlib--决策树
转载请标明出处http://www.cnblogs.com/haozhengfei/p/d65ab6ccff684db729f44a947ac9e7da.html 决策树 1.什么是决策树 决策 ...
- 虚拟主机,VPS,云主机之间的区别?
虚拟主机即共享主机,是利用虚拟技术把一台完整的服务器分成若干个主机,拥有多个网站,共享这台服务器的硬件和带宽的资源.可以托管简单的静态和动态的网站,满足客户最基本的网络托管需求. VPS是将一台物理服 ...
- 【编程技巧】applicationContext.xml 里面可配置bean和数据库地址
<bean id="vendorManagerDao" class="com.active.vendor.dao.VendorManagerDaoImpl" ...
- PostgreSQL 的 distinct on 的理解
摘录自:http://www.cnblogs.com/gaojian/archive/2012/09/05/2671381.html 对于 select distinct on , 可以利用下面的例子 ...
- python实现冒泡排序和快速排序
冒泡排序和快排的python实现: data = [1, 3, 5, 10, 4, 7] times = 0 "冒泡排序" for i in range(len(data)): f ...
- express官网学习笔记
npm init 创建一个package.json npm install express --save-dev 安装到项目依赖 便于多人开发 路由结构定义 app.METHOD(PATH, HAND ...