zoukankan      html  css  js  c++  java
  • 🔺Count on a tree SPOJ

    https://cn.vjudge.net/problem/SPOJ-COT

    插上 大佬的代码 和 我的。。。以后再看吧。。。

    Count on a tree

    大佬:http://www.cnblogs.com/Sunnie69/p/5511684.html

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    const int maxn=100000+5;
    int n,m,cnt,num;
    int a[maxn],id[maxn],b[maxn],head[maxn],p[maxn],f[maxn],root[maxn];
    bool vis[maxn];
    struct edge{
        int to,next;
        edge(){}
        edge(int a,int b):to(a),next(b){}
    }g[maxn<<1];
    struct Qry{
        int u,v,k,lca;
        Qry(){}
        Qry(int a,int b,int c,int d):u(a),v(b),k(c),lca(d){}
    }Q[maxn];
    struct node{ int l,r,s; }t[maxn*20];
    struct qry{
        int v,id;
        qry(){}
        qry(int a,int b):v(a),id(b){}
    };
    vector <qry> q[maxn];
    
    inline int find(int x){ return x==f[x]?x:f[x]=find(f[x]); }
    void add_edge(int u,int v){
        g[++cnt]=edge(v,head[u]); head[u]=cnt;
        g[++cnt]=edge(u,head[v]); head[v]=cnt;
    }
    void update(int l,int r,int &pos,int d){
        t[++num]=t[pos]; pos=num; t[pos].s++; 
        if(l==r) return;
        int mid=l+(r-l)/2;
        if(d<=mid) update(l,mid,t[pos].l,d);
        else update(mid+1,r,t[pos].r,d);
    }
    bool cmp(int x,int y){ return a[x]<a[y]; }
    void dfs(int u){
        f[u]=u; root[u]=root[p[u]]; update(1,n,root[u],b[u]);
        for(int i=head[u];i;i=g[i].next){
            if(g[i].to!=p[u]){
                p[g[i].to]=u;
                dfs(g[i].to);
                f[g[i].to]=u;
            }
        }
        vis[u]=true;
        int size=q[u].size();
        for(int i=0;i<size;i++) if(vis[q[u][i].v]) Q[q[u][i].id].lca=find(q[u][i].v);
    }
    void init(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]), id[i]=i;
        sort(id+1,id+n+1,cmp);
        for(int i=1;i<=n;i++) b[id[i]]=i;
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add_edge(u,v);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&Q[i].u,&Q[i].v,&Q[i].k);
            q[Q[i].u].push_back(qry(Q[i].v,i)); q[Q[i].v].push_back(qry(Q[i].u,i));
        }
    }
    int query(int l,int r,int x,int y,int ra,int a,int k){
        if(l==r) return l;
        int mid=l+(r-l)/2;
        int s=t[t[x].l].s+t[t[y].l].s-2*t[t[ra].l].s;
        if(b[a]>=l&&b[a]<=mid) s++;
        if(k<=s) return query(l,mid,t[x].l,t[y].l,t[ra].l,a,k);
        else return query(mid+1,r,t[x].r,t[y].r,t[ra].r,a,k-s);
    }
    void solve(){
        dfs(1);
        for(int i=1;i<=m;i++){
            if(Q[i].u==Q[i].v){ printf("%d
    ",a[Q[i].u]); continue; }
            printf("%d
    ",a[id[query(1,n,root[Q[i].u],root[Q[i].v],root[Q[i].lca],Q[i].lca,Q[i].k)]]);
        }
    }
    int main(){
        init();
        solve();
        return 0;
    }

    蒟蒻:

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define rap(a, n) for(int i=a; i<=n; i++)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 10010, INF = 0x7fffffff;
    int n, m, x, y, k, cnt;
    int root[maxn], a[maxn], f[maxn], head[maxn], vis[maxn], pre[maxn];
    struct node {int l, r, sum;}T[maxn];
    struct edge {int v, next, lca;}Edge[maxn];
    vector<int> v;
    int getid(int x) { return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;}
    vector<int> G[maxn];
    
    struct quer {int u, v, id, lca, k;}Q[maxn];
    vector<quer> q[maxn];
    void add_(int u, int v)
    {
        Edge[cnt].v = v;
        Edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    void add(int u, int v)
    {
        add_(u, v);
        add_(v, u);
    }
    
    int find(int x)
    {
        return f[x] == x?x:(f[x] == find(f[x]));
    }
    
    void update(int l, int r, int& pos, int d)
    {
        T[++cnt] = T[pos], T[cnt].sum++, pos = cnt;
        if(l == r) return;
        int mid = l + (r - l) / 2;
        if(mid >= d) update(l, mid, T[pos].l, d);
        else update(mid+1, r, T[pos].r, d);
    }
    
    void lca(int u)
    {
        f[u] = u;
        root[u] = root[pre[u]];
        update(1, n, root[u], getid(u));
        for(int i=head[u]; i!=-1; i=Edge[i].next)
        {
            int v = Edge[i].v;
            if(v == pre[u]) continue;
            pre[v] = u;
            lca(v);
            f[v] = u;
        }
        vis[u] = true;
        int size = q[u].size();
        rap(0, size-1)
        {
            if(vis[q[u][i].v])
            {
                Q[q[u][i].id].lca = find(q[u][i].v);
            }
        }
    }
    
    int query(int l, int r, int x, int y, int ra, int lca, int k)
    {
        if(l == r) return l;
        int mid = l + (r - l) / 2;
        int sum = T[T[y].l].sum + T[T[x].l].sum - 2*T[T[ra].l].sum;
        int lca_id = getid(lca);
        if(lca_id >= l && lca_id <= mid) sum++;
        if(sum >= k) return query(l, mid, T[x].l, T[y].l, T[ra].l, lca, k);
        else return query(mid+1, r, T[x].r, T[y].r, T[ra].r, lca, k - sum);
    }
    
    int main()
    {
        mem(head, -1);
        cnt = 0;
        scanf("%d%d", &n, &m);
        rap(1, n)
        {
            scanf("%d", &a[i]);
            v.push_back(a[i]);
        }
        sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end());
        rap(1, n-1)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v);
        }
        rap(1, m)
        {
            scanf("%d%d%d", &Q[i].u, &Q[i].v, &Q[i].k);
            Q[i].id = i;
            q[Q[i].u].push_back(Q[i]);
            q[Q[i].v].push_back(Q[i]);
        }
        lca(1);
        rap(1, m)
        {
            if(Q[i].u == Q[i].v)
            {
                printf("%d
    ",a[Q[i].u]);
                continue;
            }
    
            printf("%d
    ",v[query(1, n, root[Q[i].u], root[Q[i].v], root[Q[i].lca], Q[i].lca, Q[i].k) - 1]);
        }
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    Http常用请求
    大量数据导出到Excel(不使用微软Excel控件)---------------转自CSDN--rocket2010
    ASP.NET 在IIS上发布时,报错404.17 提示找不到系统文件
    PTA7-1 一元多项式的乘法与加法运算(Java实现)
    Java输入几行字符串
    看电视(贪心算法)
    出租车费(贪心算法)
    简化路径(栈实现)
    有效的括号
    链表反转
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9358947.html
Copyright © 2011-2022 走看看