BZOJ 4285 使者
我TM再也不写BIT套主席树了。。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 200500
#define maxe 200500
using namespace std;
int n,m,q,type,x,y,g[maxv],nume=,dfn[maxv],mx[maxv],fdfn[maxv],dis[maxv],anc[maxv][],times=;
int root[maxv*],sum[maxv*],tot=,ls[maxv*],rs[maxv*];
struct edge
{
int v,nxt;
}e[maxe];
void addedge(int u,int v)
{
e[++nume].v=v;
e[nume].nxt=g[u];
g[u]=nume;
}
int lowbit(int x)
{
return (x&(-x));
}
void dfs(int x,int fath)
{
dfn[x]=++times;fdfn[times]=x;mx[x]=dfn[x];
for (int i=g[x];i;i=e[i].nxt)
{
int v=e[i].v;
if (v!=fath)
{
anc[v][]=x;dis[v]=dis[x]+;
dfs(v,x);
mx[x]=max(mx[x],mx[v]);
}
}
}
void build(int &now,int left,int right)
{
now=++tot;sum[now]=;
if (left==right) return;
int mid=(left+right)>>;
build(ls[now],left,mid);
build(rs[now],mid+,right);
}
void get_table()
{
for (int e=;e<=;e++)
for (int i=;i<=n;i++)
anc[i][e]=anc[anc[i][e-]][e-];
}
int lca(int x,int y)
{
if (dis[x]<dis[y]) swap(x,y);
if (dis[x]!=dis[y])
{
for (int e=;e>=;e--)
{
if ((dis[anc[x][e]]>=dis[y]) && (anc[x][e]))
x=anc[x][e];
}
}
if (x==y) return x;
for (int e=;e>=;e--)
{
if (anc[x][e]!=anc[y][e])
{
x=anc[x][e];
y=anc[y][e];
}
}
return anc[x][];
}
int find(int x,int pos)
{
for (int e=;e>=;e--)
if (dis[anc[x][e]]>dis[pos])
x=anc[x][e];
return x;
}
void modify(int last,int x,int pos,int val)
{
root[x]=++tot;
int now=root[x];sum[now]=sum[last]+val;
int left=,right=n;
while (left<right)
{
int mid=(left+right)>>;
ls[now]=ls[last];rs[now]=rs[last];
if (pos<=mid)
{
ls[now]=++tot;
sum[ls[now]]=sum[ls[last]]+val;
now=ls[now];last=ls[last];right=mid;
}
else
{
rs[now]=++tot;
sum[rs[now]]=sum[rs[last]]+val;
now=rs[now];last=rs[last];left=mid+;
}
}
}
void add(int x,int pos,int val)
{
for (int i=x;i<=n;i+=lowbit(i))
modify(root[i],i,pos,val);
}
void build_tree()
{
build(root[],,n);
for (int i=;i<=n;i++)
{
root[i]=++tot;
ls[root[i]]=ls[root[i-]];rs[root[i]]=rs[root[i-]];
}
scanf("%d",&m);
for (int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(dfn[x],dfn[y],);
add(dfn[y],dfn[x],);
}
}
int ask(int now,int left,int right,int l,int r)
{
if ((left==l) && (right==r))
return sum[now];
int mid=(left+right)>>;
if (r<=mid) return ask(ls[now],left,mid,l,r);
else if (l>=mid+) return ask(rs[now],mid+,right,l,r);
else return ask(ls[now],left,mid,l,mid)+ask(rs[now],mid+,right,mid+,r);
}
int ask_(int now,int left,int right)
{
int ret=;
for (int i=now;i>=;i-=lowbit(i))
ret+=ask(root[i],,n,left,right);
return ret;
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);addedge(y,x);
}
dfs(,);
get_table();
build_tree();
scanf("%d",&q);
for (int i=;i<=q;i++)
{
scanf("%d%d%d",&type,&x,&y);
if (type==)
{
add(dfn[x],dfn[y],);
add(dfn[y],dfn[x],);
}
else if (type==)
{
add(dfn[x],dfn[y],-);
add(dfn[y],dfn[x],-);
}
else
{
int t=lca(x,y);
if (t==y)
{
int r=find(x,y);
int ret1=ask_(mx[x],,n)-ask_(dfn[x]-,,n);
int ret2=ask_(mx[x],dfn[r],mx[r])-ask_(dfn[x]-,dfn[r],mx[r]);
printf("%d\n",ret1-ret2);
}
else if (t==x)
{
int r=find(y,x);
int ret1=ask_(n,dfn[y],mx[y]);
int ret2=ask_(mx[r],dfn[y],mx[y])-ask_(dfn[r]-,dfn[y],mx[y]);
printf("%d\n",ret1-ret2);
}
else
printf("%d\n",ask_(mx[x],dfn[y],mx[y])-ask_(dfn[x]-,dfn[y],mx[y]));
}
}
return ;
}
BZOJ 4285 使者的更多相关文章
- BZOJ 4285 使者 (CDQ分治+dfs序)
题目传送门 题目大意:给你一棵树,有三种操作,在两个点之间连一个传送门,拆毁一个已有的传送门,询问两个点之间的合法路径数量.一条合法路径满足 1.经过且仅经过一个传送门 2.不经过起点终点简单路径上的 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- 就地交叉数组元素[a1a2b1b2]->[a1b1a2b2]
问题描述: If [a1,a2,a3...,an,b1,b2...bn] is given input change this to [a1,b1,a2,b2.....an,bn] , solutio ...
- ***百度统计图表Echarts的php实现类,支持柱形图、线形图、饼形图
/** * 百度数据统计图表echart的PHP实现类 * * 原作者: * @author: chenliujin <liujin.chen@qq.com> * @since 2013- ...
- BZOJ 2424: [HAOI2010]订货 费用流
2424: [HAOI2010]订货 Description 某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月 ...
- node操作MongoDB数据库之插入
在上一篇中我们介绍了MongoDB的安装与配置,接下来的我们来看看在node中怎样操作MongoDB数据库. 在操作数据库之前,首先应该像关系型数据库一样建个数据库把... 启动数据库 利用命令提示符 ...
- 关于null == 0?返回false的问题
1.首先我们先看各种情况的结果: null > 0? //=>false null < 0? //=>false null >= 0? //=>true null ...
- 【poj3691-DNA repair】AC自动机+DP
题意:给n个病毒DNA序列,再给一个DNA序列,问该序列至少修改多少个碱基能不含任何病毒DNA.病毒DNA序列一共不超过1000,询问的DNA长度不超过1000. 题解:DP:d[l][p]表示询问到 ...
- 李洪强iOS开发之多线程编程2-NSOperation
前言 1.上一讲简单介绍了NSThread的使用,虽然也可以实现多线程编程,但是需要我们去管理线程的生命周期,还要考虑线程同步.加锁问题,造成一些性能上的开销.我们也可以配合使用NSOperation ...
- lintcode:寻找旋转排序数组中的最小值 II
寻找旋转排序数组中的最小值 II 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 数组中可能存在重复的元 ...
- iOS开发--iOS及Mac开源项目和学习资料
文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...
- python urllib2的proxyhandler
1. 再a方法中新建了个opener,使用了代理: proxydict = {} proxydict['http'] = "http://%s:%s"%(ip,port) #pri ...