Count on a tree

Time Limit:129MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu

Description

You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.

We will ask you to perform the following operation:

  • u v k : ask for the kth minimum weight on the path from node u to node v

Input

In the first line there are two integers N and M.(N,M<=100000)

In the second line there are N integers.The ith integer denotes the weight of the ith node.

In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).

In the next M lines,each line contains three integers u v k,which means an operation asking for the kth minimum weight on the path from node u to node v.

Output

For each operation,print its result.

Example

Input:
8 5
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2 
Output:
2
8
9
105

分析:tarjan(st表)+主席树,加了一下读入挂,挺快的;
代码:
st表:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=4e6+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
int n,m,k,t,a[maxn],b[maxn],s[maxn],ls[maxn],rs[maxn],root[maxn],h[maxn],p[maxn],dep[maxn],vis[maxn],sz,num,tot,all;
pii st[][maxn];
inline ll read()
{
ll x=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void init()
{
for(int i=;i<=all;i++)p[i]=+p[i>>];
for(int i=;i<=;i++)
for(int j=;(ll)j+(<<i)-<=all;j++)
st[i][j]=min(st[i-][j],st[i-][j+(<<(i-))]);
}
int query(int l,int r)
{
int x=p[r-l+];
return min(st[x][l],st[x][r-(<<x)+]).se;
}
struct node
{
int to,nxt;
}e[maxn];
void add(int x,int y)
{
tot++;
e[tot].to=y;
e[tot].nxt=h[x];
h[x]=tot;
}
void insert(int l,int r,int x,int &y,int v)
{
y=++sz;
s[y]=s[x]+;
if(l==r)return;
ls[y]=ls[x],rs[y]=rs[x];
int mid=l+r>>;
if(v<=mid)insert(l,mid,ls[x],ls[y],v);
else insert(mid+,r,rs[x],rs[y],v);
}
int gao(int l,int r,int x,int y,int z,int k,int care)
{
if(l==r)return l;
int mid=l+r>>,j;
j=s[ls[y]]+s[ls[z]]-*s[ls[x]]+(care>=l&&care<=mid);
if(j>=k)return gao(l,mid,ls[x],ls[y],ls[z],k,care);
else return gao(mid+,r,rs[x],rs[y],rs[z],k-j,care);
}
void dfs(int now,int pre)
{
st[][++all]=mp(dep[now],now);
vis[now]=all;
insert(,num,root[pre],root[now],a[now]);
for(int i=h[now];i;i=e[i].nxt)
{
int to=e[i].to;
if(to!=pre)
{
dep[to]=dep[now]+;
dfs(to,now);
st[][++all]=mp(dep[now],now);
}
}
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
rep(i,,n)a[i]=read(),b[i]=a[i];
sort(b+,b+n+);
num=unique(b+,b+n+)-b-;
rep(i,,n)a[i]=lower_bound(b+,b+num+,a[i])-b;
rep(i,,n-)
{
int c,d;
c=read(),d=read();
add(c,d);add(d,c);
}
dfs(,);
init();
rep(i,,m)
{
int c,d,k;
c=read(),d=read(),k=read();
if(vis[c]>vis[d])swap(c,d);
int fa=query(vis[c],vis[d]);
printf("%d\n",b[gao(,num,root[fa],root[c],root[d],k,a[fa])]);
}
//system("Pause");
return ;
}

Tarjan:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=4e6+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
int n,m,k,t,a[maxn],b[maxn],s[maxn],ls[maxn],rs[maxn],root[maxn],vis[maxn],ans[maxn],fa[maxn],h[maxn],g[maxn],sz,num,tot,tot1;
struct node
{
int x,y,z;
node(){}
node(int _x,int _y,int _z):x(_x),y(_y),z(_z){};
};
struct node1
{
int to,nxt;
}e[maxn];
struct node2
{
node p;
int nxt;
}f[maxn];
void add(int x,int y)
{
tot++;
e[tot].to=y;
e[tot].nxt=h[x];
h[x]=tot;
}
void add1(int x,int y,int z,int k)
{
tot1++;
f[tot1].p=node(y,z,k);
f[tot1].nxt=g[x];
g[x]=tot1;
}
inline ll read()
{
ll x=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void insert(int l,int r,int x,int &y,int v)
{
y=++sz;
s[y]=s[x]+;
if(l==r)return;
ls[y]=ls[x],rs[y]=rs[x];
int mid=l+r>>;
if(v<=mid)insert(l,mid,ls[x],ls[y],v);
else insert(mid+,r,rs[x],rs[y],v);
}
int gao(int l,int r,int x,int y,int z,int k,int care)
{
if(l==r)return l;
int mid=l+r>>,j;
j=s[ls[y]]+s[ls[z]]-*s[ls[x]]+(care>=l&&care<=mid);
if(j>=k)return gao(l,mid,ls[x],ls[y],ls[z],k,care);
else return gao(mid+,r,rs[x],rs[y],rs[z],k-j,care);
}
void dfs(int now,int pre)
{
vis[now]=;
insert(,num,root[pre],root[now],a[now]);
for(int i=g[now];i;i=f[i].nxt)
{
node p=f[i].p;
if(vis[p.y])
{
int fa=find(p.y);
ans[p.x]=b[gao(,num,root[fa],root[now],root[p.y],p.z,a[fa])];
}
}
for(int i=h[now];i;i=e[i].nxt)
{
int to=e[i].to;
if(!vis[to])
{
dfs(to,now);
fa[to]=now;
}
}
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
rep(i,,n)a[i]=read(),b[i]=a[i],fa[i]=i;
sort(b+,b+n+);
num=unique(b+,b+n+)-b-;
rep(i,,n)a[i]=lower_bound(b+,b+num+,a[i])-b;
rep(i,,n-)
{
int c,d;
c=read(),d=read();
add(c,d);add(d,c);
}
rep(i,,m)
{
int c,d,k;
c=read(),d=read(),k=read();
add1(c,i,d,k);
add1(d,i,c,k);
}
dfs(,);
rep(i,,m)printf("%d\n",ans[i]);
//system("Pause");
return ;
}

最新文章

  1. C#数组,List,Dictionary的相互转换
  2. sql 删除重复数据且保留其中一条 用sql 关键字:with ROW_NUMBER
  3. ROW_NUMBER() OVER函数的用法
  4. SpringMVC 的RequestMapping
  5. 容器--EnumMap
  6. Java关键字this、super使用总结
  7. 用Qt写软件系列三:一个简单的系统工具之界面美化
  8. QQ登入(2)获取用户信息
  9. 一个利用window.name实现的windowStorage
  10. Linux free -m 详细说明
  11. python里面的几个编码函数
  12. VC下载文件 + 显示进度条
  13. 使用带Arduino IDE &amp; WIZ820io的ATmega1284P
  14. Android 操作系统的内存回收机制[转]
  15. TP-Link WR842N VPN错误619 不能建立到远程计算机的连接
  16. 从0到1,了解NLP中的文本相似度
  17. [翻译] 初看 ASP.NET Core 3.0 即将到来的变化
  18. ffmpeg中AVBuffer的实现分析
  19. iOS多线程编程之GCD的基本使用(转载)
  20. 事件冒泡 比bubble

热门文章

  1. 命令窗口修改编码,CMD编码修改方法
  2. 循环语句 ,for语句
  3. 【伪一周小结(没错我一周就做了这么点微小的工作)】HDOJ-1241 Oil Deposits 初次AC粗糙版对比代码框架重构版
  4. Domain=com.alamofire.error.serialization.response Code=-1016 &quot;Request failed: unacceptable content-type: text/html&quot;
  5. PHP扩展开发-简单类扩展
  6. PCI源码学习笔记
  7. oracle登陆,在监听服务启动了的情况下,登陆用户还是报错未启动监听服务的错误(刚开始装oracle是能登陆的,重启之后装了plsql)
  8. 【servlet】 第一个servlet
  9. 使用btoa和atob来进行Base64转码和解码
  10. 软件开发常用的linux命令心得(ubuntu为例)