【BZOJ3052】[wc2013]糖果公园

Description

Input

Output

Sample Input

Sample Input

Sample Output

84
131
27
84

HINT

题解:区间中的带修改的莫队做法:将块的大小设为n^2/3,将所有询问按照(l所在块,r所在块,time)排序,每次暴力移动三个指针即可。

树上莫队做法:将树按siz分块(如果fa的siz<B则加入到fa的块中,否则新建一块),将询问按(l所在块,r的DFS序)排序,每次暴力移动两个指针即可。

但是当我们扫过移动指针时,需要将经过的所有点的状态取反。但是这能处理边权。所以我们要将LCA单独拿出来特判。

所以带修改的树上莫队呢~将两者合起来就行了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=100010;
typedef long long ll;
int n,m,q,now,tot,B,sum,cnt,flag;
ll ans,f[maxn],v[maxn],w[maxn];
int fa[18][maxn],next[maxn<<1],to[maxn<<1],head[maxn],dep[maxn],siz[maxn],bel[maxn];
int pa[maxn],pb[maxn],pc[maxn],last[maxn],s[maxn],vis[maxn],c[maxn];
struct node
{
int a,b,tim,org;
}p[maxn];
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void add(int a,int b)
{
to[++cnt]=b,next[cnt]=head[a],head[a]=cnt;
}
void dfs(int x)
{
if(x==1||siz[bel[fa[0][x]]]==B) bel[x]=++sum;
else bel[x]=bel[fa[0][x]];
siz[bel[x]]++;
for(int i=head[x];i;i=next[i]) if(!dep[to[i]]) fa[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
}
bool cmp(node a,node b)
{
return (bel[a.a]==bel[b.a])?((bel[a.b]==bel[b.b])?(a.tim<b.tim):(bel[a.b]<bel[b.b])):(bel[a.a]<bel[b.a]);
}
inline void rev(int x)
{
if(!vis[x]) vis[x]=1,s[c[x]]++,ans+=v[c[x]]*w[s[c[x]]];
else vis[x]=0,ans-=v[c[x]]*w[s[c[x]]],s[c[x]]--;
}
void work(int a,int b)
{
if(dep[a]<dep[b]) swap(a,b);
while(dep[a]>dep[b]) rev(a),a=fa[0][a];
while(a!=b) rev(a),rev(b),a=fa[0][a],b=fa[0][b];
}
int lca(int a,int b)
{
if(dep[a]<dep[b]) swap(a,b);
for(int i=17;i>=0;i--) if(dep[fa[i][a]]>=dep[b]) a=fa[i][a];
if(a==b) return a;
for(int i=17;i>=0;i--) if(fa[i][a]!=fa[i][b]) a=fa[i][a],b=fa[i][b];
return fa[0][a];
}
int main()
{
n=rd(),m=rd(),q=rd();
int i,j,a,b,lc;
for(i=1;i<=m;i++) v[i]=rd();
for(i=1;i<=n;i++) w[i]=rd();
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
for(i=1;i<=n;i++) c[i]=rd();
for(i=1;i<=q;i++)
{
if(!rd()) flag=1,j=++tot,pa[j]=rd(),pb[j]=rd(),pc[j]=(!last[pa[j]])?c[pa[j]]:pb[last[pa[j]]],last[pa[j]]=j;
else j=i-tot,p[j].a=rd(),p[j].b=rd(),p[j].tim=tot,p[j].org=j;
}
if(flag) B=int(ceil(exp(log(1.0*n)*2.0/3.0)));
else B=int(sqrt(double(n)));
dep[1]=1,dfs(1);
for(j=1;(1<<j)<=n;j++) for(i=1;i<=n;i++) fa[j][i]=fa[j-1][fa[j-1][i]];
sort(p+1,p+q-tot+1,cmp);
a=b=1;
for(i=1;i<=q-tot;i++)
{
work(a,p[i].a),work(b,p[i].b),a=p[i].a,b=p[i].b;
lc=lca(a,b),rev(lc);
while(now<p[i].tim)
{
now++;
if(vis[pa[now]]) rev(pa[now]),c[pa[now]]=pb[now],rev(pa[now]);
c[pa[now]]=pb[now];
}
while(now>p[i].tim)
{
if(vis[pa[now]]) rev(pa[now]),c[pa[now]]=pc[now],rev(pa[now]);
c[pa[now]]=pc[now],now--;
}
f[p[i].org]=ans,rev(lc);
}
for(i=1;i<=q-tot;i++) printf("%lld\n",f[i]);
return 0;
}//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

【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队的更多相关文章

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

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

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

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

  3. bzoj3052: [wc2013]糖果公园

    又是一代神题. uoj测速rank10,bzoj测速rank26(截止当前2016.5.30 12:58) 带修改的树上莫队. 修改很少,块的大小随便定都能A 然而我一开始把开3次根写成了pow(bl ...

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

  5. BZOJ3052 [wc2013] 糖果公园 【树上莫队】

    树上莫队和普通的序列莫队很像,我们把树进行dfs,然后存一个长度为2n的括号序列,就是一个点进去当作左括号,出来当作右括号,然后如果访问从u到v路径,我们可以转化成括号序列的区间,记录x进去的时候编号 ...

  6. BZOJ3052: [wc2013]糖果公园【树上带修莫队】

    Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 思路 非常模板的树上带修莫队 真的 ...

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

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...

  8. 【Luogu P4074】[WC2013]糖果公园(树上带修改莫队)

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

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

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

随机推荐

  1. hdu 5974 A Simple Math Problem gcd(x,y)=gcd((x+y),lcm(x,y))

    题目链接 题意 现有\[x+y=a\\lcm(x,y)=b\]找出满足条件的正整数\(x,y\). \(a\leq 2e5,b\leq 1e9,数据组数12W\). 思路 结论 \(gcd(x,y)= ...

  2. 21深入理解C指针之---通过指针传递数据

    一.在C程序设计中,主要活动就是操纵数据 1.数据传递:将数据作为参数传入参数和将数据作为数据返回两种 2.函数: 1).函数类型:主要是指函数返回数据的类型,可以是基本类型或复杂数据类型,即使函数无 ...

  3. 驱动13.i2c设备驱动程序

    1 分析i2c设备的识别过程i2c_add_driver    i2c_register_driver        driver->driver.bus = &i2c_bus_type ...

  4. Codeforces 149D Coloring Brackets(树型DP)

    题目链接 Coloring Brackets 考虑树型DP.(我参考了Q巨的代码还是略不理解……) 首先在序列的最外面加一对括号.预处理出DFS树. 每个点有9中状态.假设0位不涂色,1为涂红色,2为 ...

  5. 标题:如何使用ShareSDK实现Cocos2d-x的Android/iOS分享与授权

    Cocos2DX 简介 Cocos2d-x是一套成熟的开源跨平台游戏开发框架.其引擎提供了图形渲染.GUI.音频.网络.物理.用户输入等丰富的功能,被广泛应用于游戏开发及交互式应用的构建.引擎的核心采 ...

  6. BZOJ1003物流運輸 DP + SPFA

    @[DP, SPFA] Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要\(n\)天才能运完.货物运输过程中一般要转 停好几个码头.物流公司通常会设计一条固定的运 ...

  7. SVG动画实践篇-音量变化效果

    git 地址:https://github.com/rainnaZR/svg-animations/tree/master/src/pages/step2/volumn 说明 这个动画的效果就是多个线 ...

  8. LINUX6.5 + MYSQL5.6 + JIRA6.3 + CONFLUENCE5.9

    #================MYSQL=============================    [root@localhost Desktop]# /sbin/ifup eth0[roo ...

  9. uva 11374 最短路+记录路径 dijkstra最短路模板

    UVA - 11374 Airport Express Time Limit:1000MS   Memory Limit:Unknown   64bit IO Format:%lld & %l ...

  10. 如何使用Medieval CUE Splitter分割ape,合并ape,制作cue

    1 下载并运行这个软件,点击打开CUE文件,然后找到需要打开的CUE文件.   2 软件会立即弹出一个再次要求打开APE文件的对话框.打开之后会发现APE音乐已经被分割成了一小段一小段.   3 点击 ...