这道题的内存…………………真·精神污染………..

这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第一关键字,另一个作为第二关键字,于是就有了两维限制,按照主席树的一般思路,我们把建树顺序作为一维,然后在里面维护另一维,那么我们在外面限制第一关键字,就是在树上建主席树,查询减LCA,在里面的话我们把每个点作为第一关键字对应的第二关键字,放入主席树,而主席树维护的是欧拉序区间,所以我们每次查询只用查询在两端点减LCA得到了一棵树里查询,其所对应的欧拉序区间里的sum,对于sum来说,一个点第一次出现的位置加+1,第二次出现的位置-1,因为我们要找的是一段连续区间里在一段路径上的sum。

欧拉序建树的内存要比直接父子关系建树大2倍左右。

#include <cstdio>
#include <cstring>
#include <ctime>
#include <vector>
#define MAXN 100001
using namespace std;
inline int read(){
int sum=;register char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')sum=(sum<<)+(sum<<)+ch-'',ch=getchar();
return sum;
}
struct Seg_Tree{
Seg_Tree *ch[];
int size;
}*root[MAXN<<],*null;
struct Via{
int to,next;
}*c;
int *head,t;
struct Bia{
int to,next,id;
}*C;
int *Head,T;
int *f;
bool *v;
vector<int> memmber[MAXN];
int Ola[MAXN<<],One[MAXN],Two[MAXN],Time,F[MAXN];
int L[MAXN],R[MAXN],Lca[MAXN];
int n,m;
//*******************Define*******************
inline void add(int x,int y){
c[++t].to=y,c[t].next=head[x],head[x]=t;
}
inline void Add(int x,int y,int z){
C[++T].to=y,C[T].next=Head[x],Head[x]=T,C[T].id=z;
}
inline int find(int x){
return x==f[x]?x:(f[x]=find(f[x]));
}
void LCA(int x,int fa){
f[x]=x;
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=fa)LCA(c[i].to,x),f[c[i].to]=x;
v[x]=;
for(int i=Head[x];i;i=C[i].next)
if(v[C[i].to])Lca[C[i].id]=find(C[i].to);
}
//********************Tarjan*******************
void dfs(int x,int fa){
Ola[++Time]=x,One[x]=Time,F[x]=fa;
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=fa) dfs(c[i].to,x);
Ola[++Time]=-x,Two[x]=Time;
}
//********************Ola**********************
void ins(Seg_Tree *&p,Seg_Tree *last,int key,int l,int r){
if(p==last)p=new Seg_Tree,p->ch[]=last->ch[],p->ch[]=last->ch[],p->size=last->size;
p->size+=Ola[key]<?-:;if(l==r)return;
if(key<=((l+r)>>))ins(p->ch[],last->ch[],key,l,((l+r)>>));
else ins(p->ch[],last->ch[],key,((l+r)>>)+,r);
}
int query(Seg_Tree *A1,Seg_Tree *A2,Seg_Tree *B1,Seg_Tree *B2,int l,int r,int z,int y){
if(z<=l&&r<=y)return A1->size-A2->size+B1->size-B2->size;int sum=;
if(z<=((l+r)>>)&&((l+r)>>)<y)return query(A1->ch[],A2->ch[],B1->ch[],B2->ch[],l,((l+r)>>),z,y)+query(A1->ch[],A2->ch[],B1->ch[],B2->ch[],((l+r)>>)+,r,z,y);
if(z<=((l+r)>>))return query(A1->ch[],A2->ch[],B1->ch[],B2->ch[],l,((l+r)>>),z,y);
if(((l+r)>>)<y)return query(A1->ch[],A2->ch[],B1->ch[],B2->ch[],((l+r)>>)+,r,z,y);
}
void Del(Seg_Tree *p,Seg_Tree *last){
if(p==last)return;
Del(p->ch[],last->ch[]),Del(p->ch[],last->ch[]);
delete p;
}
void Delete(int x,int fa){
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=fa)
Delete(c[i].to,x);
Del(root[x],root[fa]);
}
void Dfs_Build_One(int x,int fa){
root[x]=root[fa];
for(int i=;i<memmber[x].size();i++){
ins(root[x],root[fa],One[memmber[x][i]],,Time);
}
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=fa)
Dfs_Build_One(c[i].to,x);
}
void Dfs_Build_Two(int x,int fa){
root[x]=root[fa];
for(int i=;i<memmber[x].size();i++){
ins(root[x],root[fa],Two[memmber[x][i]],,Time);
}
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=fa)
Dfs_Build_Two(c[i].to,x);
}
//********************Seg_Tree******************
long long GCD(long long x,long long y){
return x==?y:GCD(y%x,x);
}
//********************GCD***********************
int main(){
c=new Via[MAXN<<],C=new Bia[MAXN<<],head=new int[MAXN],Head=new int[MAXN],f=new int[MAXN],v=new bool[MAXN];
for(int i=;i<MAXN;i++)head[i]=Head[i]=v[i]=;
n=read(),m=read();for(int i=,x,y;i<n;i++)x=read(),y=read(),add(x,y),add(y,x);
for(int i=;i<=m;i++)L[i]=read(),R[i]=read(),Add(L[i],R[i],i),Add(R[i],L[i],i),memmber[L[i]].push_back(R[i]);
LCA(,),dfs(,),null=new Seg_Tree,null->ch[]=null->ch[]=null,null->size=,root[]=null;
delete[] C,delete[] Head,delete[] f,delete[] v;
Dfs_Build_One(,);
long long ans=;
for(int i=;i<=m;i++){
ans+=query(root[L[i]],root[Lca[i]],root[R[i]],root[F[Lca[i]]],,Time,One[Lca[i]],One[L[i]]);
if(Lca[i]!=R[i])ans+=query(root[L[i]],root[Lca[i]],root[R[i]],root[F[Lca[i]]],,Time,One[Lca[i]]+,One[R[i]]);
}
Delete(,),Dfs_Build_Two(,);
for(int i=;i<=m;i++){
ans+=query(root[L[i]],root[Lca[i]],root[R[i]],root[F[Lca[i]]],,Time,One[Lca[i]],One[L[i]]);
if(Lca[i]!=R[i])ans+=query(root[L[i]],root[Lca[i]],root[R[i]],root[F[Lca[i]]],,Time,One[Lca[i]]+,One[R[i]]);
}
ans-=m;
long long x=(long long)(m-)*m/,y=GCD(ans,x);ans/=y,x/=y;
printf("%lld/%lld",ans,x);
return ;
}
//*******************Main**********************

【BZOJ 3772】精神污染 主席树+欧拉序的更多相关文章

  1. bzoj 3772 精神污染 主席树+dfs序

    精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 637  Solved: 177[Submit][Status][Discuss] Descri ...

  2. bzoj 3772 :精神污染 线段树+打标记 or 主席树

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 315  Solved: 87[Submit][Status][Discuss] D ...

  3. BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数

    BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...

  4. [BZOJ3772]精神污染 主席树上树+欧拉序

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...

  5. Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)

    题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...

  6. BZOJ 3772: 精神污染(dfs序+主席树)

    传送门 解题思路 比较神仙的一道题.首先计算答案时可以每条路径所包含的路径数,对于\(x,y\)这条路径,可以在\(x\)这处开个\(vector\)存\(y\),然后计算时只需要算这个路径上每个点的 ...

  7. bzoj 4026 dC Loves Number Theory 主席树+欧拉函数

    题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n)代 ...

  8. BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)

    3813: 奇数国 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 755  Solved: 432[Submit][Status][Discuss] ...

  9. BZOJ3772 精神污染 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3772 题意概括 给出一个树,共n个节点. 有m条互不相同的树上路径. 现在让你随机选择2条路径,问 ...

随机推荐

  1. 【Android】下拉刷新实现

    关于这方面的文章百度下有很多,我就只写写我自己实现过程. 我觉得学习一门语言不是做了几个项目就可以认为自己会了,这只是暂时的,若没有笔记,时间长了,你是怎么解决某些问题,估计连你自己都忘了,又得费时费 ...

  2. css在线sprite

    大家知道网站图片多,浏览器下载多个图片要有多个请求.可是请求比较耗时,那怎么办呢? 对,方法就是css sprite. 今天我们来看看css在线sprite 百度搜索css-sprite 打开www. ...

  3. python2.7入门---Number(数字)

        今天咱们来简单分享一下关于python中的一种数据类型和操作方法.费话不多说哈,咱们直接来进行实践加理论.首先,我们要知道,Python Number 数据类型用于存储数.数据类型是不允许改变 ...

  4. HBase 伪分布式环境搭建及基础命令使用

    一.前提条件: (1)文件存储在HDFS文件系统之上.因此必须启动hadoop服务.(namenode,datanode,resourcemanager,nodemanager,historyserv ...

  5. kafka topic 完全删除

    kafka topic 完全删除   1.自动删除脚本(得配置server.properties 中 delete.topic.enable=true) ./kafka-topics.sh --zoo ...

  6. C++各种类型的简单排序大汇总~

    啊,排序的技能点也太多了吧!!!LITTLESUN快要**在排序的技能场了啊!(划掉)经历了两天48小时2880分钟172800秒的艰苦奋斗,终于终于终于学的差不多了!明天就可以去打排序的小怪喽!(撒 ...

  7. loj2587 「APIO2018」铁人两项

    圆方树orz,参见猫的课件(apio和wc的)以及这里那里 #include <iostream> #include <cstdio> using namespace std; ...

  8. Java日志(一):log4j与.properties配置文件

    日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录,在Apache网站jakarta.apache.org/log4j可以免费下载到Log4j ...

  9. Ubuntu16.04安装Zabbix

    基于Zabbix+MySQL+Apache(可选) apt-get install php7.0-bcmath php7.0-xml php7.0-mbstring安装Zabbix所需的几个PHP模块 ...

  10. 《python核心编程第二版》第4章习题

    4–1. Python 对象.与所有 Python 对象有关的三个属性是什么?请简单的