bzoj3351:[ioi2009]Regions
思路:首先如果颜色相同直接利用以前的答案即可,可以离线排序或是在线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的更多相关文章
- BZOJ3351: [ioi2009]Regions(根号分治)
题意 题目链接 Sol 很神仙的题 我们考虑询问(a, b)(a是b的祖先),直接对b根号分治 如果b的出现次数\(< \sqrt{n}\),我们可以直接对每个b记录下与它有关的询问,这样每个询 ...
- 【dfs序】【二分】【主席树】【分块】bzoj3351 [ioi2009]Regions
http://dzy493941464.sinaapp.com/archives/96 那个SIZE貌似必须设成R*R/Q?不知为啥,自己算的不是这个的说. 本机AC,线上TLE. #include& ...
- LeetCode130:Surrounded Regions
题目: Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is capt ...
- [LeetCode]题解(python):130-Surrounded Regions
题目来源: https://leetcode.com/problems/surrounded-regions/ 题意分析: 给定给一个二维的板,这个板只包括‘X’和‘O’.将被‘X’包围的‘O’变成‘ ...
- BZOJ.3351.[IOI2009]Regions(根号分治 差分)
BZOJ 表示非常爽2333 \(Description\) 给定一棵\(n\)个点的树,每个点有一个属性\(1\leq r_i\leq R\). \(Q\)次询问,每次询问给定\(r1,r2\),求 ...
- BZOJ 3351: [ioi2009]Regions
对于一个询问(x,y)对y出现次数分类,若<=lim,在儿子处统计答案,若>lim则y的种类肯定<lim,在祖先处统计(仿佛要去重?但是没去重也过了,那个时限仿佛怎么做都能过) #i ...
- MaskRCNN:三大基础结构DeepMask、SharpMask、MultiPathNet
MaskXRCnn俨然成为一个现阶段最成功的图像检测分割网络,关于MaskXRCnn的介绍,需要从MaskRCNN看起. 当然一个煽情的介绍可见:何恺明团队推出Mask^X R-CNN,将实例分割扩展 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- [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 ...
随机推荐
- 计算智能 Computational Intelligence,CI
计算智能(Computational Intelligence,CI)是借助自然界(生物界)规律的启示,根据其规律,设计出求解问题的算法.智能计算只是一种经验化的计算机思考性程序. 计算智能算法主要包 ...
- SSDT – Error SQL70001 This statement is not recognized in this context-摘自网络
March 28, 2013 — arcanecode One of the most common errors I get asked about when using SQL Server Da ...
- Java 线程池详细介绍
根据摩尔定律(Moore’s law),集成电路晶体管的数量差不多每两年就会翻一倍.但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长.处理器制造商花了很多年来提高时钟频率和指令并行.在 ...
- Windows 2003 VPN配置步骤[转]
一,服务器端:Windows 2003 VPN代理的配置方法如下: 1.关闭防火墙,用“管理工具”中的“服务”将“Windows Firewall/Internet Connection Sharin ...
- 在Windows8工作站上安装可靠多播协议
为什么要安装可靠多播协议? 答:随着因特网的发展,出现了视频点播.电视会议.远程学习.计算机协同工作等新业务.传统的点到点通信方式,不仅浪费大量的网络带宽,而且效率很低.一种有效利用现有带宽的技术 ...
- 工作7年,从《一个苏州IT人的5年挨踢经历》系列开始,博客1年半,纯纪念
真正涉足CSDN,还是从<一个苏州IT人的5年挨踢经历>系列的发帖开始,当时大家比较捧场,遂把帖子内容整理,其后创建CSDN博客并发表于其上.有了这个开端,后续就习惯性的开始在CSDN写技 ...
- SQL SERVER全面优化
今天我们从语句的一些优化写法及一些简单优化方法做一个介绍.这对于很多开发人员来说还是很有用的!为了方便阅读给出前文链接: SQL SERVER全面优化-------Expert for SQL Ser ...
- myBatis性能优化【转】
官方doc文档 http://www.mybatis.org/mybatis-3/configuration.html#settings 最近测试发现个myBatis 有个比较严重的性能问题, 描述如 ...
- Linux下用来获取各种系统信息的C++类
#include <vector> #include "sys/config.h" SYS_NAMESPACE_BEGIN /*** * 用来获取系统.内核和进程的各类 ...
- AndroidStaggeredGrid
https://github.com/etsy/AndroidStaggeredGrid