BZOJ 4285 使者 (CDQ分治+dfs序)
题目大意:给你一棵树,有三种操作,在两个点之间连一个传送门,拆毁一个已有的传送门,询问两个点之间的合法路径数量。一条合法路径满足 1.经过且仅经过一个传送门 2.不经过起点终点简单路径上的任何一条边
这模型转化好神啊
首先把树拍成$dfs$序
问题是在树上,我们把$x,y$这条链拎出来摊平,那么链上每个点都挂了一些子树。
容易发现合法路径数=连接以$x,y$为根的子树的传送门数量
而无根树并没有“子树”这一概念,所以先随便挑一个根跑出来dfs序。
发现“子树”的$dfs$序一定是一个或两个连续的区间,我们分$x,y$是否为$lca$讨论一下就可以了
然后把问题放到二维坐标系上。
问题转化成,动态在一个二维平面内加入/删除一个点,以及查询矩形内点的数量
由于存在修改操作,需要再加上一维。那么整个问题变成了一个三维偏序问题。用$CDQ$分治+树状数组即可
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 100005
#define M1 500005
#define ll long long
#define uint unsigned int
using namespace std; template <typename _T> void read(_T &ret)
{
ret=; _T fh=; char c=getchar();
while(c<''||c>''){ if(c=='-') fh=-; c=getchar(); }
while(c>=''&&c<=''){ ret=ret*+c-''; c=getchar(); }
ret=ret*fh;
} struct Edge{
int to[N1*],nxt[N1*],head[N1],cte;
void ae(int u,int v)
{ cte++; to[cte]=v; nxt[cte]=head[u]; head[u]=cte; }
}e; int n; namespace Tree{
int dep[N1],fa[N1],ff[N1][],st[N1],ed[N1],ord[N1],cur;
void dfs1(int x)
{
int j,v; ff[x][]=x; st[x]=++cur; ord[cur]=x;//sz[x]=1;
for(j=e.head[x];j;j=e.nxt[j])
{
v=e.to[j]; if(v==fa[x]) continue;
fa[v]=x; ff[v][]=x; dep[v]=dep[x]+;
dfs1(v);
}
ed[x]=cur;
}
void init()
{
dep[]=; dfs1();
int i,j;
for(j=;j<=;j++)
for(i=;i<=n;i++)
ff[i][j]=ff[ ff[i][j-] ][j-];
}
int LCA(int x,int y)
{
int i,ans=;
if(dep[x]<dep[y]) swap(x,y);
for(i=;i>=;i--)
if(dep[ff[x][i]]>=dep[y]) x=ff[x][i];
if(x==y) return x;
for(i=;i>=;i--)
if(ff[x][i]==ff[y][i]) ans=ff[x][i];
else x=ff[x][i], y=ff[y][i];
return ans;
}
int LCB(int x,int D)
{
int i;
for(i=;i>=;i--)
if(dep[ff[x][i]]>=D) x=ff[x][i];
return x;
}
}; struct BIT{
int sum[N1];
void upd(int x,int w)
{
if(!x) return; int i;
for(i=x;i<=n;i+=(i&(-i)))
sum[i]+=w;
}
int query(int x)
{
int ans=,i;
for(i=x;i>;i-=(i&(-i)))
ans+=sum[i];
return ans;
}
void clr(int x)
{
int i;
for(i=x;i<=n;i+=(i&(-i)))
sum[i]=;
}
}bit; struct OP{ int x,y,t,type,f; }op[M1],tmp[M1];
int cmp2(OP &s1,OP &s2)
{
if(s1.x!=s2.x) return s1.x<s2.x;
if(s1.y!=s2.y) return s1.y<s2.y;
return s1.type<s2.type;
}
int ans[N1],que[M1],isquery[N1],tl; void CDQ(int L,int R)
{
if(L==R) return;
int M=(L+R)>>,i,j,cnt=;
CDQ(L,M); CDQ(M+,R);
for(i=L,j=M+;i<=M&&j<=R;)
{
if(cmp2(op[i],op[j])){
if(!op[i].type) bit.upd(op[i].y,op[i].f), que[++tl]=op[i].y;
tmp[++cnt]=op[i]; i++;
}else{
if(op[j].type) ans[op[j].t]+=op[j].f*bit.query(op[j].y);
tmp[++cnt]=op[j]; j++;
}
}
while(i<=M){ tmp[++cnt]=op[i]; i++; }
while(j<=R){ tmp[++cnt]=op[j]; if(op[j].type) ans[op[j].t]+=op[j].f*bit.query(op[j].y); j++; }
for(i=L;i<=R;i++) op[i]=tmp[i-L+];
while(tl){ bit.clr(que[tl]); tl--; }
} int m,Q1,Q2;
using Tree::st; using Tree::ed; using Tree::dep; using Tree::LCA; using Tree::LCB; int main()
{
scanf("%d",&n);
int i,j,x,y,z,F,q,fl;
for(i=;i<n;i++) read(x), read(y), e.ae(x,y), e.ae(y,x);
Tree::init();
read(Q1);
for(q=;q<=Q1;q++)
{
read(x); read(y);
op[++m]=(OP){st[x],st[y],,,}; op[++m]=(OP){st[y],st[x],,,};
}
read(Q2);
for(q=;q<=Q2;q++) { read(fl); read(x); read(y);
if(fl==){
op[++m]=(OP){st[x],st[y],q,,}; op[++m]=(OP){st[y],st[x],q,,};
}else if(fl==){
op[++m]=(OP){st[x],st[y],q,,-}; op[++m]=(OP){st[y],st[x],q,,-};
}else if(fl==){
F=LCA(x,y); isquery[q]=;
if(x==F||y==F){
if(x==F) swap(x,y); z=LCB(x,dep[F]+);
op[++m]=(OP){ed[x],st[z]-,q,,}; //op[++m]=(OP){ed[x],0,q,1,-1};
op[++m]=(OP){st[x]-,st[z]-,q,,-}; //op[++m]=(OP){st[x]-1,0,q,1,1};
op[++m]=(OP){ed[x],n,q,,}; op[++m]=(OP){ed[x],ed[z],q,,-};
op[++m]=(OP){st[x]-,n,q,,-}; op[++m]=(OP){st[x]-,ed[z],q,,};
}else{
op[++m]=(OP){ed[x],ed[y],q,,}; op[++m]=(OP){ed[x],st[y]-,q,,-};
op[++m]=(OP){st[x]-,ed[y],q,,-}; op[++m]=(OP){st[x]-,st[y]-,q,,};
}
} } CDQ(,m);
for(i=;i<=Q2;i++) if(isquery[i])
printf("%d\n",ans[i]);
return ;
}
BZOJ 4285 使者 (CDQ分治+dfs序)的更多相关文章
- 【bzoj4182】Shopping 树的点分治+dfs序+背包dp
题目描述 给出一棵 $n$ 个点的树,每个点有物品重量 $w$ .体积 $c$ 和数目 $d$ .要求选出一个连通子图,使得总体积不超过背包容量 $m$ ,且总重量最大.求这个最大总重量. 输入 输入 ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- 【BZOJ4285】使者 cdq分治+扫描线+树状数组
[BZOJ4285]使者 Description 公元 8192 年,人类进入星际大航海时代.在不懈的努力之下,人类占领了宇宙中的 n 个行星,并在这些行星之间修建了 n - 1 条星际航道,使得任意 ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ 2141: 排队 [CDQ分治]
题意: 交换序列中两个元素,求逆序对 做分块做到这道题...一看不是三维偏序嘛.... 作为不会树套树的蒟蒻就写CDQ分治吧.... 对时间分治...x排序...y树状数组... 交换拆成两个插入两个 ...
- BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ - 2809 dispatching 主席树+dfs序
在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的 ...
随机推荐
- Java - 对象(object) 具体解释
对象(object) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24059545 对象(object)的实例能够是 ...
- 云上kafka和自建kafka对比
说起Kafka,许多使用者对它是又爱又恨.Kafka是一种分布式的.基于发布/订阅的消息系统,其极致体验让人欲罢不能,但操心的运维.复杂的安全策略.可靠性易用性的缺失.算不上极致的性能发挥.并不丰富的 ...
- HDU 5311 Sequence
Hidden String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- School Personal Contest #1 (Codeforces Beta Round #38)---A. Army
Army time limit per test 2 seconds memory limit per test 256 megabytes input standard input output s ...
- URAL 1326. Bottle Taps(简单的状压dp)
题目不太好读懂,就是先给你一个n代表要从n个物品中买东西,然后告诉你这n个东西的单位价格,在给你m个集合的情况.就是每一个结合中有x件物品.他们合起来买的价格是k.这x件物品依次是:p1--px.之后 ...
- HBase无法连接ZooKeeper问题
上次搭建HBase环境后,运行登陆server时,报以下的错误: hadoop@gpmaster logs]$ hbase shell SLF4J: Class path contains multi ...
- node.js下操作cookie
cookie,又是cookie.工作中与cookie打交道很多次,不过时间跨度也大,每总结多一次,就加深了解多一点. cookie,一定是放在浏览器中的,用于浏览器保存一些小额度的内容.每次我们去访问 ...
- mp3播放时间
import os os_sep = os.sep this_file_abspath = os.path.abspath(__file__) this_file_dirname, this_file ...
- 深度学习的seq2seq模型——本质是LSTM,训练过程是使得所有样本的p(y1,...,yT‘|x1,...,xT)概率之和最大
from:https://baijiahao.baidu.com/s?id=1584177164196579663&wfr=spider&for=pc seq2seq模型是以编码(En ...
- 特征变化--->标签到向量的转换(OneHotEncoder)
一.One-Hot Encoding One-Hot编码,又称为一位有效编码,主要是采用位状态寄存器来对个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效. 在实 ...