http://uoj.ac/problem/58

http://www.lydsy.com/JudgeOnline/problem.php?id=3052

输入格式

输出格式

input

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

output

84
131
27
84

——————————————————————————————————————

这题对于一个刚学莫队的人来说……挺萌的。

首先先对树分块,具体请看我的前一篇博客王室联邦我们就可以知道,假设我们要分块,我们设预期分块大小为s,则所有块的大小可为[s,3s]。

按照这种分块方法分块即可,注意为了我们算法的速度,分块大小s=n的2/3次方,证明可看小兔大佬的博客中单点修改莫队

(dfs同时预处理LCA所需要的几个数据,以后会用)

在那之后按照莫队的思路为询问排序,然后开始我们正式的算法。

(排序时0号点的l和r都设成1(看到下面的操作之后就会知道这样做干什么了))

这里说一下个别几个数组的含义。

1.sta[i]:i是否在当前路径上,是为1.

2.last[i]:第i个操作为修改时,修改前的颜色。

3.cc[i]:最终i点的颜色。

4.col[i]:当前操作时i点的颜色。

再说一个函数rev(i)表示将i这个点在我们的路径上被添加/删除。

剩下的应该都能看得懂,我就不说什么了。

首先按照排序后顺序扫询问,我们得到了我们当前的询问和前一个询问。

那么首先我们需要将前一个询问的id和后一个询问的id中间的修改操作修改了。

然后就是最神奇的操作了,solve操作的证明详见vfk的博客

(当然你也可以通过画图肉眼观察法证明,以下简述solve内部操作)

我们把当前的左询问节点l和之前的左询问节点l0之间的最短路取反。(当然同时对右节点也是一样)

然后取反左右询问节点的LCA,再更新cur,在取反LCA,这样我们就得到了这个询问的答案了。

#include<cstdio>
#include<stack>
#include<cctype>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=;
const int INF=;
inline ll read(){
ll X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to;
int nxt;
}edge[N*];
struct qu{
int id,l,r,bl,br;
}qry[N];
int n,m,Q,q,s,cnt,head[N];
int top,idx,stk[N],blk[N];
int anc[N][],dep[N];
int v[N],cc[N],col[N],sum[N];
int a[N],b[N],op[N],last[N];
ll cur,ans[N],w[N];
bool sta[N];
inline void add(int u,int v){
cnt++;
edge[cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
bool cmp(qu d,qu e){
if(d.bl!=e.bl)return d.bl<e.bl;
if(d.br!=e.br)return d.br<e.br;
return d.id<e.id;
}
void dfs(int u){
int st=top;
dep[u]=dep[anc[u][]]+;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==anc[u][])continue;
anc[v][]=u;
dfs(v);
if(top-st>=s){
idx++;
while(top>st)blk[stk[top--]]=idx;
}
}
stk[++top]=u;
return;
}
int LCA(int i,int j){
if(dep[i]<dep[j])swap(i,j);
for(int k=;k>=;k--){
if(dep[anc[i][k]]>=dep[j])i=anc[i][k];
}
if(i==j)return i;
for(int k=;k>=;k--){
if(anc[i][k]!=anc[j][k])i=anc[i][k],j=anc[j][k];
}
return anc[i][];
}
void init(){
n=read();m=read();Q=read();s=pow(n,2.0/3.0);
for(int i=;i<=m;i++)v[i]=read();
for(int i=;i<=n;i++)w[i]=read()+w[i-];
for(int i=;i<n;i++){
int u=read(),v=read();
add(u,v);add(v,u);
}
for(int i=;i<=n;i++)cc[i]=col[i]=read();
dfs();
while(top)blk[stk[top--]]=idx;
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
anc[i][j]=anc[anc[i][j-]][j-];
}
}
return;
}
inline 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]];
return;
}
inline void solve(int x,int y){
int l=LCA(x,y);
while(x!=l)rev(x),x=anc[x][];
while(y!=l)rev(y),y=anc[y][];
return;
}
inline void modify(int x,int y){
if(!sta[x]){
col[x]=y;
return;
}
rev(x);
col[x]=y;
rev(x);
return;
}
inline void upt(int tarT,int curT){
while(curT<tarT){
curT++;
if(!op[curT])modify(a[curT],b[curT]);
}
while(curT>tarT){
if(!op[curT])modify(a[curT],last[curT]);
curT--;
}
return;
}
int main(){
init();
for(int i=;i<=Q;i++){
op[i]=read(),a[i]=read(),b[i]=read();
if(op[i]){
qry[++q].id=i;
if(blk[a[i]]>blk[b[i]])swap(a[i],b[i]);
qry[q].l=a[i];qry[q].r=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+,cmp);
qry[].l=qry[].r=;
for(int i=;i<=q;i++){
upt(qry[i].id,qry[i-].id);
solve(qry[i].l,qry[i-].l);solve(qry[i].r,qry[i-].r);
int l=LCA(qry[i].l,qry[i].r);
rev(l);
ans[qry[i].id]=cur;
rev(l);
}
for(int i=;i<=Q;i++){
if(op[i])printf("%lld\n",ans[i]);
}
return ;
}

BZOJ3052 & UOJ58:[WC2013]糖果公园——题解的更多相关文章

  1. 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队

    [BZOJ3052][wc2013]糖果公园 Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 ...

  2. ●UOJ58 [WC2013]糖果公园

    题链: http://uoj.ac/problem/58题解: 树上带修莫队. 每个块的大小为$n^{\frac{2}{3}}$,在dfs时,把点集分为若干块. 然后类似序列带修莫队,三个关键字:be ...

  3. 【bzoj3052】[wc2013]糖果公园 带修改树上莫队

    题目描述 给出一棵n个点的树,每个点有一个点权,点权范围为1~m.支持两种操作:(1)修改一个点的点权 (2)对于一条路径,求$\sum\limits_{i=1}^m\sum\limits_{j=1} ...

  4. BZOJ3052:[WC2013]糖果公园

    浅谈莫队:https://www.cnblogs.com/AKMer/p/10374756.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...

  5. 【BZOJ3052&UOJ58】糖果公园(树上带修莫队)

    题意:给定一个n个点的树,每个结点上有一种颜色c[i] 定义一条简单路径的偷税指数为simga (sigma w[i](i=0..a[j]))*v[j](j=0..m),其中a[i]为第i种颜色在路径 ...

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

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

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

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

  8. 洛谷 P4074 [WC2013]糖果公园 解题报告

    P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...

  9. AC日记——[WC2013]糖果公园 cogs 1817

    [WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cst ...

随机推荐

  1. uvaoj1339 - Ancient Cipher(思维题,排序,字符串加密)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. 记录---Testin上新手测试用例设计实战---碎乐3.2.0

    平台上给的版本是碎乐3.12版的,但是平台上给的安装包下载不了,所以加群咨询之后给出了直接去手机应用商店下载搜索到的版本的对策.所以就那应用商店中找到的3.2.0版本来设计测试用例.因为任务中没有给出 ...

  3. C++11 type_traits 之is_same源码分析

    请看源码: template<typename _Tp, _Tp __v> struct integral_constant { static const _Tp value = __v; ...

  4. Django2.1新手图文入门教程

    第一个django Web Django2.1新手图文入门教程 http://www.liujiangblog.com/blog/36/

  5. 国内版Office365实现MFA的方案(未完)

    现在二十一世纪互联版也可以实现了MFA,现在也就是2017年3月份,支持了PC,但是对移动端应用还是不支持的,请了解. 具体方法如下: 登录国内版Office365(事例为高级商业版 https:// ...

  6. [转载] RCNN/SPP/FAST RCNN/FASTER RCNN/YOLO/SSD算法简介

    RCNN: RCNN(Regions with CNN features)是将CNN方法应用到目标检测问题上的一个里程碑,由年轻有为的RBG大神提出,借助CNN良好的特征提取和分类性能,通过Regio ...

  7. Document对象内容集合

    document 文挡对象 - JavaScript脚本语言描述———————————————————————注:页面上元素name属性和JavaScript引用的名称必须一致包括大小写否则会提示你一 ...

  8. BZOJ 4815 CQOI2017 小Q的表格 欧拉函数+分块

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4815 题意概述:要认真概述的话这个题就出来了... 分析: 首先分析题目,认真研究一下修 ...

  9. Keil sct分散加载文件

    官方说明:http://www.keil.com/support/man/docs/armlink/armlink_pge1401393372646.htm

  10. Linux下实现Rsync目录同步备份

    需求:对于开发机器做目录的数据备份 测试机IP:192.168.1.100   WEB目录:/bckup/ 下面我将用一台机器来备份上面测试机 /bckup下的所有数据,并实现时时同步 备份机器IP: ...