【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052
题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]},可以单点修改颜色。(n, m, q<=100000)
#include <bits/stdc++.h>
using namespace std;
const int N=100005, M=100005;
typedef long long ll;
inline int getint() { int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') (x*=10)+=c-'0', c=getchar(); return x; }
inline void print(ll a) { if(!a) return; print(a/10); putchar('0'+(a%10));}
int ihead[N], cnt, blo[N<<1], f[N][17], FF[N], LL[N], tot, dep[N], cal[N], pos[N<<1], col[M], n, m, W[N], V[M], qu, n_ask, n_tm, col_pre[N];
ll Ans[M], ans;
bool st[N];
struct E { int next, to; }e[N<<1];
struct Q { int x, y, lca, id, tm; }q[M];
struct T { int x, y, last; }Time[M];
inline bool cmp(const Q &a, const Q &b) { return blo[a.x]==blo[b.x]?(blo[a.y]==blo[b.y]?a.tm<b.tm:blo[a.y]<blo[b.y]):blo[a.x]<blo[b.x]; }
inline void add(int x, int y) { e[++cnt]=(E){ihead[x], y}; ihead[x]=cnt; e[++cnt]=(E){ihead[y], x}; ihead[y]=cnt; }
void dfs(int x) {
pos[FF[x]=++tot]=x;
for(int i=1; i<=16; ++i) f[x][i]=f[f[x][i-1]][i-1];
for(int i=ihead[x]; i; i=e[i].next) if(e[i].to!=f[x][0])
dep[e[i].to]=dep[x]+1, f[e[i].to][0]=x, dfs(e[i].to);
pos[LL[x]=++tot]=x;
}
inline int LCA(int x, int y) {
if(dep[x]<dep[y]) swap(x, y);
int d=dep[x]-dep[y];
for(int i=16; i>=0; --i) if((d>>i)&1) x=f[x][i]; if(x==y) return x;
for(int i=16; i>=0; --i) if(f[x][i]!=f[y][i]) x=f[x][i], y=f[y][i];
return f[x][0];
}
inline void update(int x) {
if(st[x]) { ans-=(ll)V[col[x]]*W[cal[col[x]]]; --cal[col[x]]; }
else { ++cal[col[x]]; ans+=(ll)V[col[x]]*W[cal[col[x]]]; }
st[x]=!st[x];
}
inline void change(int a, int b) {
if(st[a]) { update(a); col[a]=b; update(a); }
else col[a]=b;
}
inline void timechange(int &now, int goal) {
while(now<goal) ++now, change(Time[now].x, Time[now].y);
while(now>goal) change(Time[now].x, Time[now].last), --now;
}
void work() {
int l=1, r=0, now=0, nl, nr;
sort(q+1, q+1+n_ask, cmp);
for(int i=1; i<=n_ask; ++i) {
nl=q[i].x; nr=q[i].y;
timechange(now, q[i].tm);
while(l<nl) update(pos[l++]);
while(l>nl) update(pos[--l]);
while(r<nr) update(pos[++r]);
while(r>nr) update(pos[r--]);
if(q[i].lca) update(q[i].lca);
Ans[q[i].id]=ans;
if(q[i].lca) update(q[i].lca);
}
while(r>=l) update(pos[r--]);
}
void pre() {
dfs((n+1)>>1);
int nn=n<<1, sq=pow(nn, 2.0/3)*0.5;
for(int i=1; i<=nn; ++i) blo[i]=(i-1)/sq;
for(int i=1; i<=qu; ++i) {
int type=getint(), x=getint(), y=getint();
if(!type) {
++n_tm;
Time[n_tm]=(T){x, y, col_pre[x]}; col_pre[x]=y;
continue;
}
++n_ask;
if(FF[x]>FF[y]) swap(x, y);
int lca=LCA(x, y);
if(lca==x) q[n_ask]=(Q){FF[x], FF[y], 0, n_ask, n_tm};
else q[n_ask]=(Q){LL[x], FF[y], lca, n_ask, n_tm};
}
}
int main() {
n=getint(); m=getint(); qu=getint();
for(int i=1; i<=m; ++i) V[i]=getint();
for(int i=1; i<=n; ++i) W[i]=getint();
for(int i=1; i<n; ++i) {
int x=getint(), y=getint();
add(x, y);
}
for(int i=1; i<=n; ++i) col[i]=col_pre[i]=getint();
pre();
work();
for(int i=1; i<=n_ask; ++i) print(Ans[i]), puts("");
return 0;
}
一开始我直接在每个修改之间计算答案= =然后果断T了= =QAQ
膜拜vfk.....
首先分块是三元分块!并且要进行修改的操作以及逆操作(最坏变成O(n)辣= =)
第三元就是询问的时间。
然后写完后发现还是好慢QAQ
因为我把块大小就是分成了O(n^0.5)QAQ
继续膜拜vfk
发现要分块成O(n^(2/3)).....则有O(n^(1/3))个块...然后具体证明请看 http://vfleaking.blog.163.com/blog/static/174807634201311011201627/
艾雨青大神犇教导我们,将树分块!如前所述的分块方法。当时艾雨青神犇讲题的时候的分块方法没听清 T_T,上面的分块方法是我自己YY出来的。取B = n ^ (2 / 3),设 nBlo为块的个数,用bloNum[v]来代表v所在块的编号。(block number)则同一个块内任意两结点的距离为O(n ^ (2 / 3))的。按照之前我说的方式对询问进行排序,按顺序作答。注意到(bloNum[curV], bloNum[curU])一共有nBlo ^ 2个取值。那么如果移动一次,curV还在原来的块,curU还在原来的块,这种移动的总时间复杂度是O(nBlo ^ 2 * q)的。(因为curTi还要移动)如果移动一次,curV不在原来的块,curU不在原来的块,这种移动发生的次数最多为 nBlo ^ 2。因为我是排好序的了嘛,相同块的是放在一起的。而这种移动发生一次最坏是O(n + n + q) = O(n)。(n、q是同阶的)所以这样回答所有询问,时间复杂度就是O(nBlo ^ 2 * n)的。由于B = n ^ (2 / 3),块的大小介于[B, 3 * B]之间。则nBlo = O(n ^ (1 / 3))则时间复杂度为O(n ^ (5 / 3))。
(如果不会dfs序的话请看我上一篇博文【BZOJ】3757: 苹果树
【BZOJ】3052: [wc2013]糖果公园的更多相关文章
- bzoj 3052: [wc2013]糖果公园 带修改莫队
3052: [wc2013]糖果公园 Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 506 Solved: 189[Submit][Status] ...
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...
- bzoj 3052: [wc2013]糖果公园【树上带修改莫队】
参考:http://blog.csdn.net/lych_cys/article/details/50845832 把树变成dfs括号序的形式,注意这个是不包含lca的(除非lca是两点中的一个) 然 ...
- 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法
[题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...
- 洛谷 P4074 [WC2013]糖果公园 解题报告
P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...
- AC日记——[WC2013]糖果公园 cogs 1817
[WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cst ...
- COGS1817. [WC2013]糖果公园
1817. [WC2013]糖果公园 ★★★☆ 输入文件:park.in 输出文件:park.out 简单对比时间限制:8 s 内存限制:512 MB [题目描述] Candyland ...
随机推荐
- C# 中的Singleton模式
一般写Singleton基本都是一下这个套路 class Singleton { public static Singleton instance; private Singleton() { } p ...
- gdo图形引擎中的旋转角
横滚角(Roll) bank.roll 绕y轴 z轴正向为起点逆时针方向:往左为正,往右为负,水平时为0:有效范围:-180度-180度 注:下图是从飞机的尾部-->头部方向观察所得 俯仰角( ...
- hdu 5288 数学 ****
给一个序列 定义函数f(l ,r) 为区间[l ,r] 中 的数ai不是在这个区间其他任意数aj的倍数 求所有f(l,r)之和 通过预处理,记录 a[i] 的左右边界(所谓的左右边界时 在从 a[i] ...
- Linux gnome
一.主题风格网站:gnome-look.org.deviantart.com.Linux公社 我使用的主题是:http://gnome-look.org/content/show.php/OS+X+1 ...
- 高质量C++[转]
高质量C++/C编程指南 文件状态 [ ] 草稿文件 [√] 正式文件 [ ] 更改正式文件 文件标识: 当前版本: 1.0 作 者: 林锐 博士 完成日期: 2001年7月24日 版 本 ...
- Android SDK Manager 中如果没有相应的镜像ARM XX Image
Android SDK Manager 中如果没有相应的镜像ARM XX Image 处理做法是:先更新 相应版本Android SDK Tools 然后出现 ARM XX Image
- loj 1044(dp+记忆化搜索)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26764 思路:dp[pos]表示0-pos这段字符串最少分割的回文 ...
- HDU 5875 Function (2016年大连网络赛 H 线段树+gcd)
很简单的一个题的,结果后台数据有误,自己又太傻卡了3个小时... 题意:给你一串数a再给你一些区间(lef,rig),求出a[lef]%a[lef+1]...%a[rig] 题解:我们可以发现数字a对 ...
- MySQL数据库监控
MySQL MTOP由PHP和Python开发,所以监控机需要安装PHP运行环境和Python环境.需要的核心包如下: 1.MySQL 5.0及以上(用来存储监控系统采集的数据) 2.Apache 2 ...
- loadrunner中切割strtok字符串
http://blog.sina.com.cn/s/blog_7ee076050102vamg.html http://www.cnblogs.com/lixiaohui-ambition/archi ...