思路:首先如果颜色相同直接利用以前的答案即可,可以离线排序或是在线hash,然后考虑怎么快速统计答案。

首先如果点a是点b的祖先,那么一定有点b在以点a为根的子树的dfs序区间内的,于是先搞出dfs序。

然后如果颜色a的点数很小,颜色b的点数很大,那么可以考虑枚举a的点数,然后对于每一种颜色开个vector记录一下有哪些点是这种颜色,然后按照它们的dfs序排序,就可以用颜色a中的每个点在颜色b中二分出哪些点属于以该点为根的子树对应的dfs序区间了。复杂度O(size(a)*log(size(b))),size(a)表示颜色a的vector的size()。

然后如果颜色b的点数很小,颜色a的点数很大,那么就枚举b的点数,这时要考虑的问题就成了一个点被多少段区间覆盖了,然后离散化差分预处理,再去二分(我写的是vector的离散化)。复杂度O(size(b)*log(size(a)))

但如果a,b的点数差不多且都很大(也就是几乎为sqrt(n)),那么算法复杂度就会变成O(sqrt(n)*log(n))了,再乘以一个q就会GG,于是只能另寻他法,然后可以发现直接两个指针扫过去,一个扫区间端点另一个扫要询问的点,然后如果扫到一个点就直接统计答案,然后这就变成了O(size(a)+size(b))了。

那这个很大是有多大,很小是有多小呢?

对于第一种算法使用条件是size(b)>x,第二种算法使用条件是size(a)>x,其余则用第三种算法。

对于第一、二种情况,时间复杂度最大是O(n^2logn/x),然后对于第三种则是O(n*x),然后根据基本不等式x=sqrt(nlogn),总时间复杂度为O(n*sqrt(nlogn))。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define maxn 200005
#define maxr 30000 int n,r,Q,tot,cnt;
int now[maxn],pre[*maxn],son[*maxn],color[maxn],dfn[maxn],size[maxn];
long long ans[maxn]; inline int read(){
int x=,f=;char ch=getchar();
for (;ch<''||ch>'';ch=getchar()) if (ch=='-') f=-;
for (;ch>=''&&ch<='';ch=getchar()) x=x*+ch-'';
return x*f;
} struct node{
int dfn,bo;
node(){}
node(int a,int b){dfn=a,bo=b;}
bool operator <(const node &a)const{return dfn<a.dfn;}
}; struct query{
int x,y,id;
bool operator <(const query &a)const{return x<a.x||(x==a.x&&y<a.y);}
}q[maxn]; bool cmp(int a,int b){return dfn[a]<dfn[b];} vector<int> col[maxr],val[maxr];
vector<node> v[maxr];
vector<int> fuckpps[maxr]; void add(int a,int b){
son[++tot]=b;
pre[tot]=now[a];
now[a]=tot;
} void link(int a,int b){
add(a,b),add(b,a);
} void dfs(int x,int fa){
dfn[x]=++cnt;
for (int p=now[x];p;p=pre[p])
if (son[p]!=fa) dfs(son[p],x),size[x]+=size[son[p]]+;
} int binary_search(int l,int r,int b,int pos){
int ans=-;
while (l<=r){
int mid=(l+r)>>;
if (pos>=fuckpps[b][mid]) ans=mid,l=mid+;
else r=mid-;
}
return ans+;
} long long solve1(int a,int b){
long long ans=;
for (unsigned int i=;i<col[a].size();i++){
int x=col[a][i],l=binary_search(,fuckpps[b].size()-,b,dfn[x]-),r=binary_search(,fuckpps[b].size()-,b,dfn[x]+size[x]);
ans+=r-l;
}
return ans;
} int binary_search2(int l,int r,int b,int pos){
int ans=-;
while (l<=r){
int mid=(l+r)>>;
if (v[b][mid].dfn<=pos) ans=mid,l=mid+;
else r=mid-;
}
return ans;
} long long solve2(int a,int b){
long long ans=;
for (unsigned int i=;i<col[b].size();i++){
int x=col[b][i],pos=binary_search2(,v[a].size()-,a,dfn[x]);
if (pos!=-) ans+=val[a][pos];
}
return ans;
} long long solve3(int a,int b){
long long ans=;unsigned int i=,j=,tt=;
while (i<v[a].size() && j<col[b].size())
if (v[a][i].dfn<=dfn[col[b][j]]) tt=val[a][i],i++;else ans+=tt,j++;
return ans;
} int main(){
n=read(),r=read(),Q=read();int siz=sqrt(n*log2(n));
for (int i=,x;i<=n;i++){
if (i!=) x=read(),link(i,x);
color[i]=read();col[color[i]].push_back(i);
}
dfs(,);
for (int i=;i<=n;i++) fuckpps[color[i]].push_back(dfn[i]);
for (int i=;i<=r;i++) sort(col[i].begin(),col[i].end(),cmp),sort(fuckpps[i].begin(),fuckpps[i].end());
for (int i=;i<=r;i++){
for (unsigned int j=;j<col[i].size();j++)
v[i].push_back(node(dfn[col[i][j]],)),v[i].push_back(node(dfn[col[i][j]]+size[col[i][j]]+,-));
sort(v[i].begin(),v[i].end());int sum=;
for (unsigned int j=;j<v[i].size();j++){
sum+=v[i][j].bo;
val[i].push_back(sum);
}
}
for (int i=;i<=Q;i++) q[i].x=read(),q[i].y=read(),q[i].id=i;
sort(q+,q+Q+);
for (int i=;i<=Q;i++){
if (q[i].x==q[i-].x && q[i].y==q[i-].y){ans[q[i].id]=ans[q[i-].id];continue;}
if (col[q[i].y].size()+>=siz&&col[q[i].x].size()+<siz) ans[q[i].id]=solve1(q[i].x,q[i].y);
else if (col[q[i].x].size()+>=siz&&col[q[i].y].size()+<siz) ans[q[i].id]=solve2(q[i].x,q[i].y);
else ans[q[i].id]=solve3(q[i].x,q[i].y);
}
for (int i=;i<=Q;i++) printf("%lld\n",ans[i]);
return ;
}

bzoj3351:[ioi2009]Regions的更多相关文章

  1. BZOJ3351: [ioi2009]Regions(根号分治)

    题意 题目链接 Sol 很神仙的题 我们考虑询问(a, b)(a是b的祖先),直接对b根号分治 如果b的出现次数\(< \sqrt{n}\),我们可以直接对每个b记录下与它有关的询问,这样每个询 ...

  2. 【dfs序】【二分】【主席树】【分块】bzoj3351 [ioi2009]Regions

    http://dzy493941464.sinaapp.com/archives/96 那个SIZE貌似必须设成R*R/Q?不知为啥,自己算的不是这个的说. 本机AC,线上TLE. #include& ...

  3. LeetCode130:Surrounded Regions

    题目: Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is capt ...

  4. [LeetCode]题解(python):130-Surrounded Regions

    题目来源: https://leetcode.com/problems/surrounded-regions/ 题意分析: 给定给一个二维的板,这个板只包括‘X’和‘O’.将被‘X’包围的‘O’变成‘ ...

  5. BZOJ.3351.[IOI2009]Regions(根号分治 差分)

    BZOJ 表示非常爽2333 \(Description\) 给定一棵\(n\)个点的树,每个点有一个属性\(1\leq r_i\leq R\). \(Q\)次询问,每次询问给定\(r1,r2\),求 ...

  6. BZOJ 3351: [ioi2009]Regions

    对于一个询问(x,y)对y出现次数分类,若<=lim,在儿子处统计答案,若>lim则y的种类肯定<lim,在祖先处统计(仿佛要去重?但是没去重也过了,那个时限仿佛怎么做都能过) #i ...

  7. MaskRCNN:三大基础结构DeepMask、SharpMask、MultiPathNet

    MaskXRCnn俨然成为一个现阶段最成功的图像检测分割网络,关于MaskXRCnn的介绍,需要从MaskRCNN看起. 当然一个煽情的介绍可见:何恺明团队推出Mask^X R-CNN,将实例分割扩展 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. [LeetCode] Walls and Gates 墙和门

    You are given a m x n 2D grid initialized with these three possible values. -1 - A wall or an obstac ...

随机推荐

  1. HW1.5

    public class Solution { public static void main(String[] args) { System.out.println("(9.5 * 4.5 ...

  2. Tutorial: Getting Started with SignalR (C#) -摘自网络

    Overview This tutorial introduces SignalR development by showing how to build a simple browser-based ...

  3. Introduction to SignalR -摘自网络

    What is SignalR? ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of ...

  4. vmware 8下ubuntu 13.04安装vmware tools

    在虚拟机vmware 8.0里安装了ubuntu 13.04.为了方便与主机交互,安装vmware tools. 解压后直接运行 ./vmware-install.pl 一路默认路径安装下来,到&qu ...

  5. system partition table

    转载内容 摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强--System Partitioning 系统分区的特点 ●系统分区与其他分区相比,一个最根本的区别就是不需要 ...

  6. eclipse安装插件checkstyle

    最近听说了一个eclipse神器:checkstyle,可以帮助java开发人员规范代码,对我这种有代码洁癖的人来说,这有着不小的魔力啊,必然要安装试一试啊. 我最喜欢的安装方式是 输入一个安装网址, ...

  7. 让ie9之前的版本支持canvas

    原来google的研发人员早就帮我们解决了这问题. 在这里我们得首先感谢google 在这链接http://excanvas.sourceforge.net/ 下载下来后 吧excanvas.js引入 ...

  8. NotificationListenerService不能监听到通知

    作者:Hugo链接:https://www.zhihu.com/question/33540416/answer/113706620来源:知乎著作权归作者所有,转载请联系作者获得授权. 背景知识: 所 ...

  9. UIPickerView实现省 市 区三级联动

    前几天用UIPickerView实现了一下三级联动具体的如下图

  10. 移动终端学习一:css3 Media Queries简介

    移动终端学习之一 css3 Media Queries简介 1.简介 别人写过的我就不重复了,来个链接:http://www.w3cplus.com/content/css3-media-querie ...