BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目:
UOJ也能评测
题解
请看代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
typedef long long ll;
using namespace std;
const int N = 1e5 + ;
int n,m,Q,q,V[N],col[N],sum[N],last[N],blk[N];
int S,Bsum,Log[N],que[N],dep[N],fa[N][];
int Tp[N],A[N],B[N],cc[N];
int tot,info[N],nxt[N*],go[N*];
ll cur,ans[N],W[N];
bool sta[N];//sta数组记录这个节点是否在cur的计算中
int read()
{
int ret=,neg=;char j=getchar();
for (;j>'' || j<'';j=getchar()) if (j=='-') neg=-;
for (;j>='' && j<='';j=getchar()) ret=ret*+j-'';
return ret*neg;
}
struct node
{
int x,y,bl,br,id;
bool operator < (const node &k)const
{
if (bl!=k.bl) return bl<k.bl;
if (br!=k.br) return br<k.br;
return id<k.id;
}
}qry[N];
void add(int x,int y)
{
nxt[++tot]=info[x];info[x]=tot;go[tot]=y;
nxt[++tot]=info[y];info[y]=tot;go[tot]=x;
}
void Dfs(int x,int F)
{
int y,st=tot;dep[x]=dep[F]+;fa[x][]=F;
for (int i=;fa[x][i];i++)
fa[x][i+]=fa[fa[x][i]][i];
for (int k=info[x];y=go[k],k;k=nxt[k])
if (y!=F)
{
Dfs(y,x);
if (tot-st>=S)
{
while (tot>st) blk[que[tot--]]=Bsum;
++Bsum;
}
}
que[++tot]=x;
}
int LCA(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
for (int i=Log[d];i>=;i--)
if (<<i&d) x=fa[x][i];
if (x==y) return x;
for (int i=Log[dep[x]];i>=;i--)
if (fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
}
void Rev(int x)//取反操作
{
cur-=W[sum[col[x]]]*V[col[x]];
sta[x]?--sum[col[x]]:++sum[col[x]];
sta[x]=!sta[x];
cur+=W[sum[col[x]]]*V[col[x]];
}
void Modify(int x,int y)
{
if (!sta[x])
return (void)(col[x]=y);
Rev(x);col[x]=y;Rev(x);
}
void Log_Init()
{
Log[]=-;
for (int i=;i<=n;i++)
Log[i]=Log[i>>]+;
}
void Solve(int x,int y)
{
int Lca=LCA(x,y);
while (x!=Lca) Rev(x),x=fa[x][];//把路径上的点取反
while (y!=Lca) Rev(y),y=fa[y][];
}
void upt(int tarT,int curT)
{
while (curT < tarT)
{
++curT;
if (!Tp[curT]) Modify(A[curT], B[curT]);//进行修改
}
while (curT > tarT)
{
if (!Tp[curT]) Modify(A[curT], last[curT]);//撤销修改
--curT;
}
}
int main()
{
n=read();m=read();Q=read();S=pow(n,2.0/3.0);
//S是块的大小
for (int i=;i<=m;i++) V[i]=read();
for (int i=;i<=n;i++) W[i]=read(),W[i]+=W[i-];
for (int i=;i<n;i++) add(read(),read());
for (int i=;i<=n;i++) cc[i]=col[i]=read();
tot=;Log_Init();Dfs(,);
//以出栈顺序作为Dfs序,并处理每个点在哪一块,块从0标号
while (tot) blk[que[tot--]]=Bsum-;
for (int i=;i<=Q;i++)
{
Tp[i]=read();A[i]=read();B[i]=read();
if (Tp[i])
{
qry[++q].id=i;
if (blk[A[i]]>blk[B[i]]) swap(A[i],B[i]);//保证a[i]的块在b[i]左边
qry[q].x=A[i];qry[q].y=B[i];qry[q].bl=blk[A[i]];qry[q].br=blk[B[i]];
}
else last[i]=cc[A[i]],cc[A[i]]=B[i];//记录修改操作前后是啥
}
sort(qry+,qry+q+);qry[].x=qry[].y=;
for (int i=;i<=q;i++)
{
upt(qry[i].id,qry[i-].id);//更新/撤销上一个询问到这个询问中间的修改操作
Solve(qry[i].x,qry[i-].x);Solve(qry[i].y,qry[i-].y);
//从上次询问的点移动到这次的询问并更新cur
int L=LCA(qry[i].x,qry[i].y);
Rev(L);ans[qry[i].id]=cur;Rev(L);
}
for (int i=;i<=Q;i++)
if (Tp[i]) printf("%lld\n",ans[i]);
return ;
}
BZOJ 3052: [wc2013]糖果公园 | 树上莫队的更多相关文章
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- 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]糖果公园 带修改莫队
3052: [wc2013]糖果公园 Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 506 Solved: 189[Submit][Status] ...
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- 【WC2013】 糖果公园 - 树上莫队
问题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩.糖果公园的结构十分奇特,它由 n 个游览点构成, ...
- 【WC2013】糖果公园 [树上莫队]
题意: 一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和 sro VFK 树上莫队 按照王室联邦的方法分块,块的大小直径个数有保证,并不 ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- bzoj 3052: [wc2013]糖果公园【树上带修改莫队】
参考:http://blog.csdn.net/lych_cys/article/details/50845832 把树变成dfs括号序的形式,注意这个是不包含lca的(除非lca是两点中的一个) 然 ...
随机推荐
- 使用JDBC操作数据库
准备工作 1.创建一个java项目导入mysql驱动包 2.在src目录中创建一个新的Java类 JDBC查询: package com.ATedu.test; import java.sql.Con ...
- 【c学习-3】
---恢复内容开始--- #include<stdio.h> int main(){ ]={,,,,}; ; ;i<=;i++){ printf("%d\n",a ...
- Nginx 配置继承模型
要了解nginx的继承模型,首先需要知道nginx使用多个配置块进行操作.在nginx中,这样的块被称为上下文,例如,放置在服务器上下文中的配置指令驻留在server { }块中,就像放置在http上 ...
- 生产-消费模式的synchronized和lock实现(十)
lock: package com.net.thread.lock; import java.util.concurrent.locks.Condition; import java.util.con ...
- Permute Digits 915C
You are given two positive integer numbers a and b. Permute (change order) of the digits of a to con ...
- 关于修改zeppelin的代码显示
最近我在修改zeppelin(0.7版本)的源码相关的知识,目前做的工作是修改zeppelin的代码,为了让zeppelin可以可以在页面中显示数据集,并且在其数据库中存储式真实的路径1.如果我们要运 ...
- P3365 改造二叉树
P3365 改造二叉树 链接 分析: 求出中序遍历后,然后使其变成上升子序列.过程:每个点减去坐标,然后nlogn求出最长不下降子序列,n-ans即答案. 做题时一直认为二叉树就是完全二叉树,然后一直 ...
- 算法:枚举法---kotlin
枚举法:效率低,循环所有的情况,找到正确答案 用于解决数学问题,还是很简单的. 比如,奥数里面: 算 法 描 述 题X题=题题题题题题 其中 算法描述题每一个为一个数字,请写出正确的数字. ok,我们 ...
- Java - ArrayList List 等迭代集合执行移除(remove) 的正确方法
方法1: List<String> al = new ArrayList<String>(); Iterator<String> it = al.iterator( ...
- javascript md5 二次加密 和 java md5 二次加密结果不同
最近研究httpclient post 时遇到了一个问题,很费解. js md5(str) 和 java md5(str),第一次md5 加密结果一样,(当时忽略了大小写问题,java 大写,js小 ...