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 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 82 5 12 5 22 5 32 5 47 8 2 
Output:
2891057 分析: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+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;
}
时间: 2024-10-09 17:14:00

SPOJ Count on a tree的相关文章

BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

2588: Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数表示点i的权值. 后面N-1行每行两个整数(x,y),表示点x到点y有一条边. 最后M行每行两个整数(u,v,k),表示一组询问.

bzoj 2588: Spoj 10628. Count on a tree LCA+主席树

2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数

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[Submit][Status][Discuss] Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一

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

[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数表示点i的权值. 后面N-1行每行两个整数(x,y),表示点x到点y有一条边. 最后M行每行两个整数(u,v,k),表示一组

spoj COT2 - Count on a tree II

COT2 - Count on a tree II http://www.spoj.com/problems/COT2/ #tree 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 : ask for how many

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

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/JudgeOnline/problem.php?id=2588 Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Inp

Count on a tree SPOJ 主席树+LCA(树链剖分实现)(两种存图方式)

Count on a tree SPOJ 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)[GO!] 题意 是说有棵树,每个节点上都有一个值,然后让你求从一个节点到另一个节点的最短路上第k小的值是多少. 解题思路 看到这个题一想以为是树链剖分+主席树,后来写着写着发现不对,因为树链剖分我们分成了一小段一小段,这些小段不能合并起来求第k小,所以这个想法不对.奈何不会做,查了查题解,需要用LCA(最近公共祖先),然后根据主席树具有区间加减的性质,我们

spoj cot: Count on a tree 主席树

10628. Count on a tree Problem code: COT 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