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 ;
}

SPOJ Count on a tree的更多相关文章

  1. SPOJ Count on a tree(主席树+LCA)

    一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to  ...

  2. [SPOJ]Count on a tree II(树上莫队)

    树上莫队模板题. 使用欧拉序将树上路径转化为普通区间. 之后莫队维护即可.不要忘记特判LCA #include<iostream> #include<cstdio> #incl ...

  3. 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 ...

  4. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  5. 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 ...

  6. 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 ...

  7. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  8. 【BZOJ2589】 Spoj 10707 Count on a tree II

    BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...

  9. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

随机推荐

  1. mysql分页的问题

    用过mysql的人肯定知道,mysql提供了原生的分页功能-----LIMIT关键字.LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.LIMIT 接受一个或两个数字参数.参数必须是 ...

  2. HDU 5352 MZL's City

    最小费用最大流,因为要控制字典序,网络流控制不好了...一直WA,所以用了费用流,时间早的费用大,时间晚的费用少. 构图: 建立一个超级源点和超级汇点.超级源点连向1操作,容量为K,费用为COST,然 ...

  3. MFC通过ODBC连接Mysql程序

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 MFC通过ODBC连接 ...

  4. 一个机器学习博客 ,包括 Standford公开课machine learning

    http://blog.csdn.net/abcjennifer/article/category/1173803/4 http://blog.csdn.net/abcjennifer/article ...

  5. C语言strtok()函数:字符串分割

    头文件:#include <string.h> 定义函数:char * strtok(char *s, const char *delim); 函数说明:strtok()用来将字符串分割成 ...

  6. flash/flex 编译错误汇总

    来源:http://blog.chinaunix.net/uid-366408-id-116463.html 代码 消息 说明   1000 对 %s 的引用不明确. 引用可能指向多项.例如,下面使用 ...

  7. PHP中字符串转换为数值 可能会遇到的坑

    今天看到一个老外最喜欢的一段代码 <?php $string = 'zero'; $zero = 0; echo ($string == $zero) ? 'Why? Just why?!' : ...

  8. Linux启动流程详解【转载】

    在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多:一般就是通电.BIOS.主引导记录.操作系统这四步.所以我们一般认为加载内核是linux启动流程的第一步. 第一步.加载内核 操作系统接 ...

  9. 使用composer命令创建laravel项目命令详解

    composer命令创建laravel项目的命令是: composer create-project --prefer-dist laravel/laravel blog "5.2.*&qu ...

  10. Photoshop基础,前景背景,图层,选取

    1*前景色背景色 Alt+Delete 键 前景色填充 Ctrl+Delete 键 背景色填充 X 颜色转换 D 颜色互换 两个填充的原因: 2*图层(只要做东西就要建图层)透明的纸进行叠加,尽量多建 ...