【BZOJ4285】使者

Description

公元 8192 年,人类进入星际大航海时代。在不懈的努力之下,人类占领了宇宙中的 n 个行星,并在这些行星之间修建了 n - 1 条星际航道,使得任意两个
行星之间可以通过唯一的一条路径互相到达。
同时,在宇宙中还有一些空间跳跃点,有些跳跃点已经被发现,还有一些是未知的,每个跳跃点连接了两个行星,使得这两个行星中的任意一个都可以通过这个跳跃点到达另外一个行星。这些跳跃点因为充斥着巨大的能量,所以它们很容易崩溃。
宇宙中还有一些意图毁灭人类的外星人,他们派出了一些使者潜伏在行星上。现在这些使者想要离开他们各自藏身的行星u,到其他行星 v 去搜集情报。
由于这些使者十分小心, 他们不会经过任意一条属于这两个行星的路径上的星际航道(即不会走在 u 到 v 路径上的星际航道) 。这样他们就只能借助一些跳跃点
来到达目的地,但是这些外星人的身体十分脆弱,所以他们只能通过最多一个跳跃点。
现在告诉你若干个按照时间顺序给出的事件,每个事件可能是一个跳跃点又被发现了,也可能是一个跳跃点崩溃了,还有可能是一个外星使者想离开行星u到行星v去。
请问每个外星使者有多少条不同的路径可以选择?

Input

第一行一个正整数n。
接下来n - 1 行每行两个整数u, v,表示一条星际航道连接行星 u 与行星 v。
接下来一行一个正整数m,表示已经被发现的跳跃点个数。
接下来m行每行两个整数s, t,表示一个跳跃点连接行星 s与行星 t。
接下来一行一个正整数q,表示事件个数。
接下来q 行每行为以下三种事件中的一种:
“1 x y” :表示有一个连接行星x与行星 y的跳跃点被发现了;
“2 x y” :表示有一个连接行星 x 与行星 y 的跳跃点崩溃了(保证存在这样
一个跳跃点) ;
“3 x y” :表示有一个外星使者想从行星x到行星 y去搜集情报。

Output

对于每个外星使者输出一行一个整数, 表示这个外星使者可以选择的不同路径条数。

Sample Input

13
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

3
1

HINT

对于100%的数据,n ≤ 10^5,m ≤ 5 × 10^4,q ≤ 5 × 10^4 数据保证x不等于y

题解:又是精神污染。

我们将每个跳跃点看成在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分治+扫描线+树状数组的更多相关文章

  1. [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)

    [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...

  2. bzoj 1176 cdq分治套树状数组

    题面: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Inp ...

  3. 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 ...

  4. 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 ...

  5. BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716 怎么KD树跑得都那么快啊..我写的CDQ分治被暴虐 做四遍CDQ分治,每次求一个 ...

  6. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  7. 【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)

    传送门 CJOJ Solution 考虑这是一个四维偏序对吧. 直接cdq套在一起,然后这题有两种实现方法(树状数组的更快!) 代码实现1(cdq+cdq+cdq) /* mail: mleautom ...

  8. bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)

    Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...

  9. 【模板】cdq分治代替树状数组(单点修改,区间查询)

    #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #in ...

随机推荐

  1. 使用RAID与LVM磁盘阵列技术。

    7.2 LVM逻辑卷管理器 前面学习的硬盘设备管理技术虽然能够有效地提高硬盘设备的读写速度以及数据的安全性,但是在硬盘分好区或者部署为RAID磁盘阵列之后,再想修改硬盘分区大小就不容易了.换句话说,当 ...

  2. 2012关闭ECN

    Windows Server 2012 关闭TCP ECN (2014-03-20 18:22:42) 转载▼ 标签: it 分类: windows

  3. MFC HTTP GET 请求

    //HTTP GET 下载文件 CInternetSession *pInetSession = new CInternetSession(AfxGetAppName(),1,PRE_CONFIG_I ...

  4. e595. Drawing an Image

    See also e575 The Quintessential Drawing Program and e594 Reading an Image or Icon from a File. publ ...

  5. 用 #include <filename.h> 格式来引用标准库的头文件

    用 #include <filename.h> 格式来引用标准库的头文件(编译器将从 标准库目录开始搜索). #include <iostream> /* run this p ...

  6. Nodejs入门手记 (01):Hello World的WEB程序

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Allong,谢谢! “滚滚长江东逝水,浪花淘尽英雄.是非成败转头空.” - <临江仙·杨慎·明> 很熟悉的旋律,鸡汤了一下:高考是 ...

  7. c/c++函数指针(3)

    原文地址:http://blog.csdn.net/qingshuiyangfan/article/details/7692647 学习要点: 1,函数地址的一般定义和typedef简化定义;     ...

  8. 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果(转)

    转载:http://blog.csdn.net/xiaanming/article/details/10163203 了解二维码这个东西还是从微信 中,当时微信推出二维码扫描功能,自己感觉挺新颖的,从 ...

  9. chrome浏览器默认启动时打开2345导航的解决方法

    2345并没有改动chrome内部设置.它仅仅是把全部的快捷方式改动了.包含開始菜单旁边的快捷启动图标. 仅仅须要右键chrome快捷方式.在目标一栏中,把"----chrome.exe&q ...

  10. C++ string char[] 转化

    可见到string转char[]相当简单,只要呼叫string class的成员函式c_str(),即可将string转为char[].那么char[]转string呢?有两种方法,第一种是初始str ...