【BZOJ4999】This Problem Is Too Simple!

Description

给您一颗树,每个节点有个初始值。
现在支持以下两种操作:
1. C i x(0<=x<2^31) 表示将i节点的值改为x。
2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。

Input

第一行有两个整数N,Q(1 ≤N≤ 100,000;1 ≤Q≤ 200,000),分别表示节点个数和操作个数。
下面一行N个整数,表示初始时每个节点的初始值。
接下来N-1行,每行两个整数x,y,表示x节点与y节点之间有边直接相连(描述一颗树)。
接下来Q行,每行表示一个操作,操作的描述已经在题目描述中给出。

Output

对于每个Q输出单独一行表示所求的答案。

Sample Input

5 6
10 20 30 40 50
1 2
1 3
3 4
3 5
Q 2 3 40
C 1 40
Q 2 3 40
Q 4 5 30
C 3 10
Q 4 5 30

Sample Output

0
1
1
0

题解:由于每种颜色相互独立,可以考虑离线。将修改操作变成一个颜色的删除操作和另一个颜色的加入操作,然后将所有操作和询问都按颜色和时间排序,分别处理每一个颜色。然后我们只需要倍增LCA+动态维护所有点到根路径上的权值即可。单点权值+a等于它子树中所有点到根路径上的权值都+a,所以用树状数组维护DFS序即可。

竟然因为数组开小而WA了一天~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=200010;
int n,m,Q,cnt,now,tot;
struct node
{
int col,x,val,tim;
}p[maxn*5];
struct QUERY
{
int col,a,b,tim,org;
}q[maxn];
char str[10];
int to[maxn<<1],next[maxn<<1],head[maxn],p1[maxn],p2[maxn],dep[maxn],fa[19][maxn],v[maxn];
int Log[maxn],s[maxn],vis[maxn],ans[maxn];
void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x)
{
p1[x]=++p2[0];
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[0][x])
fa[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
p2[x]=p2[0];
}
bool cmpp(node a,node b)
{
return (a.col==b.col)?(a.tim<b.tim):(a.col<b.col);
}
bool cmpq(QUERY a,QUERY b)
{
return (a.col==b.col)?(a.tim<b.tim):(a.col<b.col);
}
void updata(int x,int val)
{
for(int i=x;i<=n;i+=i&-i)
{
if(vis[i]<now) vis[i]=now,s[i]=0;
s[i]+=val;
}
}
int query(int x)
{
int i,ret=0;
for(i=x;i;i-=i&-i)
{
if(vis[i]<now) vis[i]=now,s[i]=0;
ret+=s[i];
}
return ret;
}
int lca(int a,int b)
{
if(dep[a]<dep[b]) swap(a,b);
for(int i=Log[dep[a]-dep[b]];i>=0;i--) if(dep[fa[i][a]]>=dep[b]) a=fa[i][a];
if(a==b) return a;
for(int i=Log[dep[a]];i>=0;i--) if(fa[i][a]!=fa[i][b]) a=fa[i][a],b=fa[i][b];
return fa[0][a];
}
inline 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;
}
int main()
{
n=rd(),m=rd();
int i,j,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) v[i]=p[++tot].col=rd(),p[tot].x=i,p[tot].tim=0,p[tot].val=1;
for(i=2;i<=n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
dep[1]=1,dfs(1);
for(i=2;i<=n;i++) Log[i]=Log[i>>1]+1;
for(j=1;(1<<j)<=n;j++) for(i=1;i<=n;i++) fa[j][i]=fa[j-1][fa[j-1][i]];
for(i=1;i<=m;i++)
{
scanf("%s",str),a=rd(),b=rd();
if(str[0]=='C')
{
tot+=2,p[tot-1].x=p[tot].x=a,p[tot-1].col=v[a],v[a]=p[tot].col=b;
p[tot-1].tim=p[tot].tim=i,p[tot-1].val=-1,p[tot].val=1;
}
else q[++Q].a=a,q[Q].b=b,q[Q].col=rd(),q[Q].org=Q,q[Q].tim=i;
}
sort(p+1,p+tot+1,cmpp);
sort(q+1,q+Q+1,cmpq);
for(i=j=1;i<=Q;i++)
{
for(;(p[j].col<q[i].col||(p[j].col==q[i].col&&p[j].tim<q[i].tim))&&j<=tot;j++)
{
now=p[j].col;
updata(p1[p[j].x],p[j].val),updata(p2[p[j].x]+1,-p[j].val);
}
if(now==q[i].col)
{
a=q[i].a,b=q[i].b,c=lca(a,b);
ans[q[i].org]=query(p1[a])+query(p1[b])-query(p1[c])-query(p1[fa[0][c]]);
}
}
for(i=1;i<=Q;i++) printf("%d\n",ans[i]);
return 0;
}

【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA的更多相关文章

  1. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  2. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  3. 13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 2224: Boring Counting Time Limit: 3 Sec   ...

  4. Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化

    D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...

  5. Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)

    http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的 ...

  6. HDU 4417 离线+树状数组

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. bzoj 2434: 阿狸的打字机 fail树+离线树状数组

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...

  8. 【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)

    pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon c ...

  9. POJ 3416 Crossing --离线+树状数组

    题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...

随机推荐

  1. nodejs递归创建目录

    var fs = require("fs"); var path = require("path"); // 递归创建目录 异步方法 function mkdi ...

  2. windows下apache+php配置 问题总结

    以下为转帖内容: 原文出处:http://www.cnblogs.com/angelox/archive/2008/10/09/1306732.html PHP5+APACHE2.2配置成功案例:第一 ...

  3. 2016北京集训测试赛(十七)Problem A: crash的游戏

    Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \ ...

  4. centos7.3 开放端口 防火墙端口

    1. 查看已打开的端口 # netstat -anp 2. 查看想开的端口是否已开 # firewall-cmd --query-port=666/tcp 若此提示 FirewallD is not ...

  5. advanced-performance-troubleshooting-waits-latches-spinlocks

    https://www.sqlskills.com/blogs/paul/advanced-performance-troubleshooting-waits-latches-spinlocks/

  6. 聊聊、Zookeeper Linux 集群服务

    今天是平安夜,先祝大家平安夜快乐.这篇文章我们来谈谈 Zookeeper Linux 集群. 为什么要集群呢?因为一台服务不够.集群是为了系统扩容,系统稳定.一台服务挂了,没关系,我还有其他的服务.集 ...

  7. iOS UI Element Usage

    Bars The Status Bar

  8. weblogic多池与oracle集群RAC

    http://www.techpaste.com/2013/04/soa-infra-start-fails-weblogic-common-resourceexception-good-connec ...

  9. xml 文件不给提示(以mybatis 的 mapper映射文件为例)

    在xxx.xml 映射文件的头部可以看到 如下: (mybatis generate 自动生成) <!DOCTYPE mapper PUBLIC "-//mybatis.org//DT ...

  10. AutoCAD如何输入文字

    1 运行文字命令(这里使用单行文字),然后鼠标点击文字的起始点,如图所示   2 鼠标分别向上和向右移动一定距离,表示文字的高度(文字的大小)和文字的旋转角度(一般向右,因为是水平文字)   3 最后 ...