SPOJCOT2 Count on a tree II
分析
树上莫队裸题。
好博客
树剖的时候不能再次dfs重儿子。(好像是废话,但我因为这个问题调了三小时)
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x){
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;
const int MAXN=1e5+7;
int n,q;
map<int,int>M;
int a[MAXN],id;
int belong[MAXN],block;
struct Edge
{
int nx,to;
}E[MAXN<<2];
int head[MAXN],ecnt;
void addedge(int x,int y)
{
E[++ecnt].to=y;
E[ecnt].nx=head[x],head[x]=ecnt;
}
int fa[MAXN],dep[MAXN],sz[MAXN],son[MAXN],top[MAXN];
int st[MAXN],ed[MAXN],pot[MAXN],clk;
void dfs1(int x,int f)
{
fa[x]=f,sz[x]=1;
st[x]=++clk,pot[clk]=x;
dep[x]=dep[f]+1;
for(int i=head[x];i;i=E[i].nx)
{
int y=E[i].to;
if(y==f)
continue;
dfs1(y,x);
sz[x]+=sz[y];
if(sz[y]>sz[son[x]])
son[x]=y;
}
ed[x]=++clk,pot[clk]=x;
}
void dfs2(int x,int topf)
{
top[x]=topf;
if(!son[x])
return;
dfs2(son[x],topf);
for(int i=head[x];i;i=E[i].nx)
{
int y=E[i].to;
if(y==fa[x]||y==son[x]) // edit 1:cannot dfs son[x] twice and wrongly
continue;
dfs2(y,y);
}
}
int lca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
struct Quiz
{
int l,r,f,id;
bool operator<(const Quiz&x)
{
if(belong[l]^belong[x.l])
return l<x.l;
else
return r<x.r;
}
}Q[MAXN];
int ql,qr,res;
bool used[MAXN];
int cnt[MAXN],ans[MAXN];
void add(int x)
{
if(++cnt[x]==1)
++res;
}
void del(int x)
{
if(--cnt[x]==0)
--res;
}
void change(int x)
{
used[x]?del(a[x]):add(a[x]);
used[x]^=1;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);read(q);
block=sqrt(n);
for(int i=1;i<=n;++i)
{
read(a[i]);
if(!M[a[i]])
M[a[i]]=++id;
a[i]=M[a[i]];
}
for(int i=1;i<=2*n;++i) // edit 1:belong should be inited to 2n
belong[i]=(i-1)/block+1;
for(int i=1;i<n;++i)
{
int x,y;
read(x);read(y);
addedge(x,y);
addedge(y,x);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=q;++i)
{
int x,y;
read(x);read(y);
if(st[x]>st[y])
swap(x,y);
int f=lca(x,y);
if(f==x)
Q[i].l=st[x],Q[i].r=st[y];
else
Q[i].l=ed[x],Q[i].r=st[y],Q[i].f=f;
Q[i].id=i;
}
sort(Q+1,Q+q+1);
ql=1,qr=0,res=0;
for(int i=1;i<=q;++i)
{
while(ql>Q[i].l)
change(pot[--ql]);
while(qr<Q[i].r)
change(pot[++qr]);
while(ql<Q[i].l)
change(pot[ql++]);
while(qr>Q[i].r)
change(pot[qr--]);
if(Q[i].f)
change(Q[i].f);
ans[Q[i].id]=res;
if(Q[i].f)
change(Q[i].f);
}
for(int i=1;i<=q;++i)
printf("%d\n",ans[i]);
// fclose(stdin);
// fclose(stdout);
return 0;
}
SPOJCOT2 Count on a tree II的更多相关文章
- SPOJcot2 Count on a tree II (树上莫队)
You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer ...
- 【SPOJ10707】 COT2 Count on a tree II
SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...
- 【BZOJ2589】 Spoj 10707 Count on a tree II
BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...
- 【BZOJ2589】[SPOJ10707]Count on a tree II
[BZOJ2589][SPOJ10707]Count on a tree II 题面 bzoj 题解 这题如果不强制在线就是一个很\(sb\)的莫队了,但是它强制在线啊\(qaq\) 所以我们就用到了 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- spoj COT2 - Count on a tree II
COT2 - Count on a tree II http://www.spoj.com/problems/COT2/ #tree You are given a tree with N nodes ...
- AC日记——Count on a tree II spoj
Count on a tree II 思路: 树上莫队: 先分块,然后,就好办了: 来,上代码: #include <cmath> #include <cstdio> #inc ...
- SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)
COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from ...
- COT2 - Count on a tree II(树上莫队)
COT2 - Count on a tree II You are given a tree with N nodes. The tree nodes are numbered from 1 to N ...
随机推荐
- 12月22日 update_columns,完成第9节。
Update_columns(attributes) //等同于update_column 直接更新database. 使用UPdate SQL 语法. ⚠️ :忽略了validations, Cal ...
- Android Webview 和Javascript交互,实现Android和JavaScript相互调用
在Android的开发过程中.遇到一个新需求.那就是让Java代码和Javascript代码进行交互.在IOS中实现起来很麻烦.而在Android中相对来说容易多了.Android对这种交互进行了很好 ...
- Confluence 6 选项 1 – 在 Confluence 中手动重建用户和用户组
当你只有少量的用户和用户组的时候,使用这个方法. 使用 Confluence 的系统管理员登录 Confluence. 进入用户目录管理界面,然后移动 内部目录(internal directory) ...
- 『PyTorch』第九弹_前馈网络简化写法
『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下 在前面的例子中,基本上都是将每一层的输出直接作为下一层的 ...
- 『Pandas』数据读取&DataFrame切片
读取文件 numpy.loadtxt() import numpy as np dataset_filename = "affinity_dataset.txt" X = np.l ...
- UVA-10026 Shoemaker's Problem (贪心)
题目大意:一个鞋匠,有n只鞋要修,修某只鞋的时间ti已知,某只鞋晚修一天要交的罚款fi也已知.现在让找个修鞋顺序使得罚款最少. 题目分析:本来想水一下这道题,没想到真的AC啦.后来又查的题解,找的解释 ...
- Linux的三种网络适配器
Linux的三种网络适配器 分别为:桥接模式(Bridged),NAT模式,仅主机模式. 仅主机模式: 2>NAT模式 NAT 是虚拟机和本地网络使用一个ip地址 3>桥接模 ...
- OC @property @synthesize和id
文顶顶 OC语言@property @synthesize和id OC语言@property @synthesize和id 一.@property @synthesize关键字 注意:这两个关键字 ...
- ora2pg安装及卸载
--ora2pg安装 tar xzf ora2pg-10.x.tar.gz or tar xjf ora2pg-10.x.tar.bz2 cd ora2pg-10.x/ perl Makefile. ...
- curl常用功能
<?php //创建一个新cURL资源 $ch = curl_init(); //******************************************************** ...