首页 > 代码库 > SPOJ Count on a tree

SPOJ Count on a tree

Count on a tree
Time Limit:129MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu
Submit Status Practice SPOJ COT

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 5105 2 9 3 8 5 7 71 2        1 31 43 53 63 74 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2 
Output:2
8
9
105

分析: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|1const int maxn=4e6+10;using namespace std;ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}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=0;int f=1;char ch=getchar();    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}    while(ch>=0&&ch<=9){x=x*10+ch-0;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]+1;    if(l==r)return;    ls[y]=ls[x],rs[y]=rs[x];    int mid=l+r>>1;    if(v<=mid)insert(l,mid,ls[x],ls[y],v);    else insert(mid+1,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>>1,j;    j=s[ls[y]]+s[ls[z]]-2*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+1,r,rs[x],rs[y],rs[z],k-j,care);}void dfs(int now,int pre){    vis[now]=1;    insert(1,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(1,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,1,n)a[i]=read(),b[i]=a[i],fa[i]=i;    sort(b+1,b+n+1);    num=unique(b+1,b+n+1)-b-1;    rep(i,1,n)a[i]=lower_bound(b+1,b+num+1,a[i])-b;    rep(i,1,n-1)    {        int c,d;        c=read(),d=read();        add(c,d);add(d,c);    }    rep(i,1,m)    {        int c,d,k;        c=read(),d=read(),k=read();        add1(c,i,d,k);        add1(d,i,c,k);    }    dfs(1,0);    rep(i,1,m)printf("%d\n",ans[i]);    //system("Pause");    return 0;}

SPOJ Count on a tree