BZOJ2588: Spoj 10628. Count on a tree
刚开始看错题以为是dfs序瞎搞..
后来看清题了开始想用树剖瞎搞...
感觉要滚粗啊..
对于每个点到根的路径建立线段树,暴力建MLE没跑,上主席树,然后$(x,y)$的路径就可以先求出来$LCA$,然后就可以用$T_x+T_y-T_{LCA}-T_{fa[LCA]}$就行了。
//BZOJ 2588 //by Cydiater //2016.12.8 #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <iomanip> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <ctime> #include <bitset> #include <set> #include <vector> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define Auto(i,node) for(int i=LINK[node];i;i=e[i].next) const int MAXN=1e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();ll x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int N,M,dfn[MAXN],dfs_clock=0,fsort[MAXN],val[MAXN],root[MAXN],rnum=0,cnt=0,fa[MAXN][25],ans=0; struct Graph{ int LINK[MAXN],len,dep[MAXN]; struct edge{ int y,next; }e[MAXN<<1]; inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;} inline void Insert(int x,int y){insert(x,y);insert(y,x);} void make_graph(){ N=read();M=read(); up(i,1,N)val[i]=fsort[i]=read(); sort(fsort+1,fsort+N+1); rnum=unique(fsort+1,fsort+N+1)-(fsort+1); up(i,1,N)val[i]=lower_bound(fsort+1,fsort+rnum+1,val[i])-fsort; up(i,1,N-1){ int x=read(),y=read(); Insert(x,y); } } void dfs(int node,int deep,int father){ dfn[++dfs_clock]=node; dep[node]=deep;fa[node][0]=father; Auto(i,node)if(e[i].y!=father) dfs(e[i].y,deep+1,node); } void set_anc(){ up(i,1,20)up(node,1,N) if(fa[node][i-1])fa[node][i]=fa[fa[node][i-1]][i-1]; } int LCA(int x,int y){ if(x==y) return x; if(dep[x]<dep[y]) swap(x,y); down(i,20,0)if(dep[x]-(1<<i)>=dep[y])x=fa[x][i]; if(x==y) return x; down(i,20,0)if(fa[x][i]!=0&&fa[x][i]!=fa[y][i]){ x=fa[x][i]; y=fa[y][i]; } return fa[x][0]; } }G; struct Chair_man_Tree{ int son[2],sum; }t[MAXN<<5]; namespace solution{ int NewNode(int sum,int son0,int son1){ t[++cnt].sum=sum;t[cnt].son[0]=son0;t[cnt].son[1]=son1; return cnt; } void insert(int leftt,int rightt,int &Root,int last,int pos){ Root=NewNode(t[last].sum+1,t[last].son[0],t[last].son[1]); int mid=(leftt+rightt)>>1; if(leftt==rightt) return; if(pos<=mid) insert(leftt,mid,t[Root].son[0],t[last].son[0],pos); else insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos); } void Prepare(){ G.make_graph(); G.dfs(1,0,0); G.set_anc(); up(i,1,N){ int node=dfn[i],father=fa[node][0],pos=val[node]; insert(1,rnum,root[node],root[father],pos); } } int Get(int leftt,int rightt,int rx,int ry,int rlca,int rflca,int rnk){ int sum=t[t[rx].son[0]].sum+t[t[ry].son[0]].sum-t[t[rlca].son[0]].sum-t[t[rflca].son[0]].sum; if(leftt==rightt) return fsort[leftt]; int mid=(leftt+rightt)>>1; if(rnk<=sum) return Get(leftt,mid,t[rx].son[0],t[ry].son[0],t[rlca].son[0],t[rflca].son[0],rnk); else return Get(mid+1,rightt,t[rx].son[1],t[ry].son[1],t[rlca].son[1],t[rflca].son[1],rnk-sum); } void Slove(){ while(M--){ int x=read()^ans,y=read(),k=read(),lca=G.LCA(x,y); printf("%d",ans=Get(1,rnum,root[x],root[y],root[lca],root[fa[lca][0]],k)); if(M)puts(""); } } } int main(){ //freopen("input.in","r",stdin); using namespace solution; Prepare(); Slove(); return 0; }
BZOJ2588: Spoj 10628. Count on a tree的更多相关文章
- bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)
每个节点继承父节点的树,则答案为query(root[x]+root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]) #include<iostream> #i ...
- 【主席树】bzoj2588 Spoj 10628. Count on a tree
每个点的主席树的root是从其父转移来的.询问的时候用U+V-LCA-FA(LCA)即可. #include<cstdio> #include<algorithm> using ...
- 主席树初探--BZOJ2588: Spoj 10628. Count on a tree
n<=100000的点权树,有m<=100000个询问,每次问两个点间的第k小点权,保证有解,强制在线. 主席上树啦!类似于之前的序列不带修改询问的前缀表示法,现在只要把前缀当成某点到根的 ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...
- Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- 2588: Spoj 10628. Count on a tree
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5766 Solved: 1374 ...
随机推荐
- gulp-uglify 与gulp.watch()配合使用时遇到的重复压缩问题
今天学习gulp时候,用到gulp-uglify压缩js模块,遇到的一个问题-当用gulp.watch来监听js文件的变动时出现重复压缩的问题 目录结构如下: gulpfile.js代码如下: var ...
- 2015 Autodesk 开发者日( DevDays)和 助力开发周火热报名中
Autodesk 软件(中国)有限公司 ADN 市场部真诚地邀请您参加我们一年一度的 "Autodesk 开发者日"(简称 DevDays),以及第一次随同开发者日举办的" ...
- OuNews 简单的新闻客户端应用源码
一直想练习MVP模式开发应用,把学习的RxJava.Retrofit等热门的开源库结合起来,于是写了这么一款新闻阅读软件, 有新闻.图片.视频三大模块,使用Retrofit和Okhttp实现无网读缓存 ...
- 个人作业week3——代码复审
1. 软件工程师的成长 感想 看了这么多博客,收获颇丰.一方面是对大牛们的计算机之路有了一定的了解,另一方面还是态度最重要,或者说用不用功最重要.这些博客里好些都是九几年或者零几年就开始学习编 ...
- [C#6] 1-using static
0. 目录 C#6 新增特性目录 1. 老版本的代码 1 using System; 2 3 namespace csharp6 4 { 5 internal class Program 6 { 7 ...
- javascript设计模式-工厂方法模式
工厂方法模式笔记 通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例 对于创建多类对象,简单工厂不太实用,这是简单工厂模式的应用局限,当然这正是工厂方法模式的价值之所在 通过工厂方法模 ...
- Rocksdb Compaction原理
概述 compaction主要包括两类:将内存中imutable 转储到磁盘上sst的过程称之为flush或者minor compaction:磁盘上的sst文件从低层向高层转储的过程称之为compa ...
- PHP中的数据库二、memcache
:first-child, ol li > :first-child, ul li ul:first-of-type, ol li ol:first-of-type, ul li ol:firs ...
- windows中,端口查看&关闭进程及Kill使用
测试过程中遇到的问题,杂记一: 1.netstat -ano | findstr "8001" 查看端口8001被哪个进程占用:由下图可以看出,被进程为3736的占用 2.查 ...
- plain framework 1 网络流 缓存数据详解
网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...