BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线
Description
Input
Output
#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
#define maxn 300000
using namespace std;
struct OPT
{
int type;
int a,b,c,tag;
OPT(int type=0,int a=0,int b=0,int c=0,int tag=0):type(type),a(a),b(b),c(c),tag(tag){}
}opt[maxn];
vector<OPT>G[maxn];
struct BIT
{
#define N 300000
int C[maxn];
int lowbit(int t)
{
return t & (-t);
}
void update(int x,int delta)
{
while(x<N)
{
C[x]+=delta;
x+=lowbit(x);
}
}
int query(int x)
{
int tmp=0;
while(x>0)
{
tmp+=C[x];
x-=lowbit(x);
}
return tmp;
}
}tree;
char str[10];
int n,Q,edges,tot,tim,mkk=0;
int col[maxn],Arr[maxn],hd[maxn],to[maxn<<1],nex[maxn<<1],dfn[maxn],ln[maxn],st[maxn],ed[maxn];
int siz[maxn],hson[maxn],dep[maxn],top[maxn],fa[maxn],answer[maxn];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs1(int u,int ff)
{
ln[++tim]=u,dfn[u]=st[u]=tim,siz[u]=1,dep[u]=dep[ff]+1,fa[u]=ff;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[hson[u]]) hson[u]=v;
}
ed[u]=tim;
}
void dfs2(int u,int tp)
{
top[u]=tp;
if(hson[u]) dfs2(hson[u],tp);
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==fa[u]||v==hson[u]) continue;
dfs2(v,v);
}
}
int LCA(int x,int y)
{
while(top[x]^top[y]) dep[top[x]] > dep[top[y]] ? x = fa[top[x]] : y = fa[top[y]];
return dep[x]<dep[y]?x:y;
}
void solve(int cur)
{
for(int i=0,sz=G[cur].size();i<sz;++i)
{
OPT cn=G[cur][i];
switch(cn.type)
{
case -1:
{
int u=cn.a;
tree.update(st[u], -1);
tree.update(ed[u]+1, +1);
break;
}
case 1 :
{
int u=cn.a;
tree.update(st[u], 1);
tree.update(ed[u]+1, -1);
break;
}
case 2 :
{
int u=cn.a;
int v=cn.b;
int c=cn.c;
int g=cn.tag;
int lca = LCA(u,v);
answer[g]=tree.query(dfn[u])+tree.query(dfn[v])-tree.query(dfn[lca])-tree.query(dfn[fa[lca]]);
break;
}
}
}
for(int i=0,sz=G[cur].size();i<sz;++i)
{
OPT cn=G[cur][i];
if(cn.type==-1) tree.update(st[cn.a], +1), tree.update(ed[cn.a]+1,-1);
if(cn.type==1) tree.update(st[cn.a], -1), tree.update(ed[cn.a]+1, +1);
}
}
int main()
{
// setIO("input");
scanf("%d%d",&n,&Q);
for(int i=1;i<=n;++i) scanf("%d",&col[i]),Arr[++tot]=col[i];
for(int i=1;i<n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y), add(y,x);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=Q;++i)
{
scanf("%s",str);
switch(str[0])
{
case 'C' :
{
opt[i].type=1;
scanf("%d%d",&opt[i].a,&opt[i].b);
Arr[++tot]=opt[i].b;
break;
}
case 'Q' :
{
opt[i].type=2;
scanf("%d%d%d",&opt[i].a,&opt[i].b,&opt[i].c);
Arr[++tot]=opt[i].c;
break;
}
}
}
sort(Arr+1,Arr+1+tot);
for(int i=1;i<=Q;++i)
{
if(opt[i].type==1) opt[i].b=lower_bound(Arr+1,Arr+1+tot,opt[i].b)-Arr;
if(opt[i].type==2) opt[i].c=lower_bound(Arr+1,Arr+1+tot,opt[i].c)-Arr;
}
for(int i=1;i<=n;++i)
{
col[i]=lower_bound(Arr+1,Arr+1+tot,col[i])-Arr;
G[col[i]].push_back(OPT(1,i,0,0,0));
}
for(int i=1;i<=Q;++i)
{
if(opt[i].type==2)
{
OPT P=opt[i];
P.tag=++mkk;
G[opt[i].c].push_back(P);
}
else
{
int u=opt[i].a,v=opt[i].b;
G[col[u]].push_back(OPT(-1,u,0,0,0));
G[v].push_back(OPT(1,u,0,0,0));
col[u]=v;
}
}
for(int i=1;i<maxn;++i)
{
if(G[i].size()) solve(i);
}
for(int i=1;i<=mkk;++i)
{
printf("%d\n",answer[i]);
}
return 0;
}
BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线的更多相关文章
- POJ 2763 Housewife Wind(DFS序+LCA+树状数组)
Housewife Wind Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 11419 Accepted: 3140 D ...
- HDU 6203 ping ping ping(dfs序+LCA+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连 ...
- HDU 3966 dfs序+LCA+树状数组
题目意思很明白: 给你一棵有n个节点的树,对树有下列操作: I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k ...
- BZOJ 2819: Nim dfs序维护树状数组,倍增
1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...
- BZOJ 1103: [POI2007]大都市meg(dfs序,树状数组)
本来还想链剖的,结果才发现能直接树状数组的= = 记录遍历到达点与退出点的时间,然后一开始每个到达时间+1,退出时间-1,置为公路就-1,+1,询问直接点1到该点到达时间求和就行了- - CODE: ...
- 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...
- 【Tyvj2133&BZOJ1146】网络管理Network(树套树,DFS序,树状数组,主席树,树上差分)
题意:有一棵N个点的树,每个点有一个点权a[i],要求在线实现以下操作: 1:将X号点的点权修改为Y 2:查询X到Y的路径上第K大的点权 n,q<=80000 a[i]<=10^8 思路: ...
- 【POJ3321】Apple Tree(DFS序,树状数组)
题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000 思路:最近一段时间在思考树上统计问题的算法 发 ...
- 【BZOJ1103】大都市meg(DFS序,树状数组)
题意:有一颗树,1号点为根,保证编号小的点深度较小,初始状态每条边都没有被标记,要求实现两个操作在线: A:将连接x,y的边标记 W:查询从1到x的路径上有多少条边未被标记 n<=2*10^5 ...
随机推荐
- nyoj_42_一笔画问题_201403181935
一笔画问题 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...
- springmvc 解析xml数据
springmvc 解析xml数据 http://blog.csdn.net/zhi_jun/article/details/37925475
- double x = 10 ,y = 0;y = x % 2; 这个表达式正确吗?
The remainder function and % operator. 以下这段代码过不了编译的(gcc) #include <stdio.h> #include <fenv. ...
- C++<iomanip>控制符
C++<iomanip>控制符 c++ cout 输出格式 在c++程序里面经常见到下面的头文件 #include <iomanip> io代表输入输出,manip是manip ...
- tflearn中计算混淆矩阵方法——需要经过一步转换
def do_rnn_wordbag(trainX, testX, trainY, testY): y_test=testY #trainX = pad_sequences(trainX, maxle ...
- 【POJ 1456】 Supermarket
[题目链接] http://poj.org/problem?id=1456 [算法] 贪心 + 堆 [代码] #include <algorithm> #include <bitse ...
- DCloud-MUI:事件管理
ylbtech-DCloud-MUI:事件管理 极简的JS函数 1.返回顶部 1.事件绑定 除了可以使用addEventListener()方法监听某个特定元素上的事件外, 也可以使用.on()方法实 ...
- 自顶向下(递归)的归并排序和自底向上(循环)的归并排序——java实现
归并排序有两种实现方式,自顶向下和自底向上.前者的思想是分治法,现将数组逐级二分再二分,分到最小的两个元素后,逐级往上归并,故其核心在于归并.后者的思想相反,采用循环的方式将小问题不断的壮大,最后变成 ...
- Coursera Algorithms week1 查并集 练习测验:3 Successor with delete
题目原文: Given a set of n integers S = {0,1,…,N-1}and a sequence of requests of the following form: Rem ...
- 0428-mysql(事务、权限)
1.事务 “事务”是一种可以保证“多条语句一次性执行完成”或“一条都不执行”的机制. 两种开始事务的方法: 1.set autocommit = 0; //false,此时不再是一条语句一个事务了, ...