【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. Web API(一);Restful架构

    一.什么是RESTful REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移.REST指的是一组架构约束条件和原则.如果一个 ...

  2. Springboot 之 Hibernate自动建表(Mysql)

    Springboot 之 Hibernate自动建表(Mysql) 2016年10月21日 10:39:44 阅读数:8180 本文章来自[知识林] 引入Maven依赖包 <dependency ...

  3. JS中的数字比较

    if(parseInt(current_index)!=parseInt(uls)){

  4. 如果分配给命令的连接位于本地挂起事务中,ExecuteNonQuery 要求命令拥有事务。命令的 Transaction 属性尚未初始化

    DbConnection dbc = database.CreateConnection(); DbTransaction dbtt = null; try { dbc.Open(); dbtt = ...

  5. Linux Vi/Vim 的使用及实例

    什么是 vim? Vim是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用. 简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是 ...

  6. jQuery异步请求模拟IE登录网站

    具体请求的登录验证页面后台逻辑处理,这里我们忽略,不在我们的学习范围内:关键的是使用jQuery异步请求方法,如下例子: <%@ Page Language="C#" Aut ...

  7. 验证手机号码的JS方法

    function Checkreg() { //验证电话号码手机号码,包含153,159号段 if (document.form.phone.value=="" && ...

  8. 图像的降采样与升采样(二维插值)----转自LOFTER-gengjiwen

    图像的降采样与升采样(二维插值) 1.先说说这两个词的概念: 降采样,即是采样点数减少.对于一幅N*M的图像来说,如果降采样系数为k,则即是在原图中 每行每列每隔k个点取一个点组成一幅图像.降采样很容 ...

  9. hadoop3.1.0 window win7 基础环境搭建

    https://blog.csdn.net/wsh596823919/article/details/80774805 hadoop3.1.0 window win7 基础环境搭建 前言:在windo ...

  10. 拼凑sql语句另外一个方法

    经常拼凑sql语句,经常是手工拼写 也可以利用字典另外一个模式拼凑 这里采用的是Dictionary中的Aggregate方法. 代码如下: static void Main(string[] arg ...