【BZOJ4285】使者 cdq分治+扫描线+树状数组
【BZOJ4285】使者
Description
Input
Output
Sample Input
1 2
1 3
1 4
2 5
5 9
5 10
5 11
10 13
3 6
4 7
4 8
7 12
6
2 4
10 12
9 8
6 7
3 11
7 10
5
1 1 5
3 5 4
2 7 10
2 10 12
3 5 4
Sample Output
1
HINT
题解:又是精神污染。
我们将每个跳跃点看成在DFS序中二维平面上的一个点,将询问看成若干个矩形,那么就是问你矩形中点的个数,用树状数组+扫描线即可。但是有加点删点怎么办呢?套上cdq分治即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100010;
int n,m,Q,cnt,np,nq,now;
int to[maxn<<1],next[maxn<<1],head[maxn],fa[20][maxn],Log[maxn],dep[maxn],siz[maxn],p1[maxn],p2[maxn];
int s[maxn],tim[maxn],op[maxn],ans[maxn];
struct point
{
int x,y,k,org;
point() {}
point(int a,int b,int c,int d) {x=a,y=b,k=c,org=d;}
}p[maxn];
struct QUERY
{
int l,r,x,k,org;
QUERY() {}
QUERY(int a,int b,int c,int d,int e) {l=a,r=b,x=c,k=d,org=e;}
}q[maxn<<1];
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x)
{
siz[x]=1,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]),siz[x]+=siz[to[i]];
p2[x]=p2[0];
}
inline int FA(int x,int y)
{
for(int i=Log[y];i>=0;i--) if(y>=(1<<i)) y-=(1<<i),x=fa[i][x];
return x;
}
bool cmpx(const point &a,const point &b)
{
return a.x<b.x;
}
bool cmqx(const QUERY &a,const QUERY &b)
{
return a.x<b.x;
}
inline void updata(int x,int v)
{
for(int i=x;i<=n;i+=i&-i)
{
if(tim[i]<now) tim[i]=now,s[i]=0;
s[i]+=v;
}
}
inline int query(int x)
{
int ret=0,i;
for(i=x;i;i-=i&-i)
{
if(tim[i]<now) tim[i]=now,s[i]=0;
ret+=s[i];
}
return ret;
}
void solve(int l,int r,int L,int R)
{
if(l==r)
{
for(int i=L;i<=R;i++) if(p[l].org<q[i].org&&p[l].x<=q[i].x&&p[l].y>=q[i].l&&p[l].y<=q[i].r)
ans[q[i].org]+=p[l].k*q[i].k;
return ;
}
if(L>R) return ;
int mid=(l+r)>>1,MID,i,j;
for(i=L;i<=R;i++) if(q[i].org>p[mid].org) break;
MID=i-1;
solve(l,mid,L,MID),solve(mid+1,r,MID+1,R);
sort(p+l,p+mid+1,cmpx),sort(q+MID+1,q+R+1,cmqx);
now++;
for(i=MID+1,j=l;i<=R;i++)
{
for(;j<=mid&&p[j].x<=q[i].x;j++) updata(p[j].y,p[j].k);
ans[q[i].org]+=(query(q[i].r)-query(q[i].l-1))*q[i].k;
}
}
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();
int i,j,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
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]];
m=rd();
for(i=1;i<=m;i++)
{
a=rd(),b=rd();
if(p1[a]>p1[b]) swap(a,b);
p[++np]=point(p1[a],p1[b],1,0);
}
Q=rd();
for(i=1;i<=Q;i++)
{
op[i]=rd(),a=rd(),b=rd();
if(p1[a]>p1[b]) swap(a,b);
if(op[i]==1) p[++np]=point(p1[a],p1[b],1,i);
if(op[i]==2) p[++np]=point(p1[a],p1[b],-1,i);
if(op[i]==3)
{
if(p1[b]<=p2[a])
{
c=FA(b,dep[b]-dep[a]-1);
q[++nq]=QUERY(p1[b],p2[b],p1[c]-1,1,i);
q[++nq]=QUERY(p2[c]+1,n,p1[b]-1,-1,i),q[++nq]=QUERY(p2[c]+1,n,p2[b],1,i);
}
else q[++nq]=QUERY(p1[b],p2[b],p1[a]-1,-1,i),q[++nq]=QUERY(p1[b],p2[b],p2[a],1,i);
}
}
solve(1,np,1,nq);
for(i=1;i<=Q;i++) if(op[i]==3) printf("%d\n",ans[i]);
return 0;
}
【BZOJ4285】使者 cdq分治+扫描线+树状数组的更多相关文章
- [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)
[APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...
- bzoj 1176 cdq分治套树状数组
题面: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Inp ...
- bzoj 4991 [Usaco2017 Feb]Why Did the Cow Cross the Road III(cdq分治,树状数组)
题目描述 Farmer John is continuing to ponder the issue of cows crossing the road through his farm, intro ...
- HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)
Jam's problem again Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716 怎么KD树跑得都那么快啊..我写的CDQ分治被暴虐 做四遍CDQ分治,每次求一个 ...
- UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- 【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)
传送门 CJOJ Solution 考虑这是一个四维偏序对吧. 直接cdq套在一起,然后这题有两种实现方法(树状数组的更快!) 代码实现1(cdq+cdq+cdq) /* mail: mleautom ...
- bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)
Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...
- 【模板】cdq分治代替树状数组(单点修改,区间查询)
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #in ...
随机推荐
- linux实现防止恶意扫描 PortSentry
linux实现防止恶意扫描 PortSentry 脚本 open 摘要: 端口做为服务器的大门安全很重要,当服务器运行很多服务时并向外提供服务,为防止有人恶意侦测服务器用途,可使用portsent ...
- iOS基础--UIView的常见属性
UIView的常见属性以及方法 @property(nonatomic,readonly) UIView *superview; // 获得自己的父控件对象 @property(nonatomic,r ...
- @Configuration和@Bean的用法和理解
spring Boot提倡约定优于配置,如何将类的生命周期交给spring 1.第一种自己写的类,Controller,Service. 用@controller @service即可 2.第二种,集 ...
- Error -27740: WSA_IO_pending
Error -27740: WSA_IO_pendingAction.c(198): Error -27791: Server **** has shut down the connection pr ...
- android中文api(79)——Gallery
前言 本章内容是 android.widget.Gallery,版本为Android 2.3 r1,翻译来自"henly.zhang",欢迎大家访问他的博客:http://www. ...
- fastx tookit 操作fasta/fastq 文件 (1)
准备测试文件 test.fq, 包含4条fastq 文件,碱基编码格式为phred64; @FC12044_91407_8_200_406_24 NTTAGCTCCCACCTTAAGATGTTTA + ...
- C# 延时小函数 很好用
平时我们在做winform开发的时候,有时候需要让程序休眠几秒钟,但是,如果我们直接使用 thread.sleep()函数,页面ui就会停止响应.怎么样解决呢,你可以把页面涉及到表现ui的代码放到一个 ...
- linux(十一)之初始化文件
前面写了很多linux的知识,其实很多都是命令的,所以要去多多的练习才能学的更好,加油为了好工作. 要么现在懒惰,未来讨饭.要么现在努力,未来惬意. 一.初始化文件概述 1.1.概述 系统初始化文件是 ...
- 根据PV量来确定需要进行压测的并发量
在实际做压力测试的过程中,我们有时不知道用怎样的并发量比较好,下面是几个用PV量去确定并发量的公式,这个在我们公司是比较适用的,大家可以根据自己的业务进行运算. 方法一:这个方法是我在网上查到的80- ...
- C#委托和事件详解
委托Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持 ...