南昌网络赛 Distance on the tree 主席树+树剖 (给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数。)

https://nanti.jisuanke.com/t/38229

题目:

给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数。

 

 
#include <bits/stdc++.h>
#define mid (l+r>>1)
#define lson (o<<1)
#define rson (o<<1|1)
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 2e5+1000;
vector<int>nxt[N],len[N];
int fa[N],deep[N],id[N],siz[N],son[N],tot,s[N],top[N],ss[N];
int n,m;
int SIZ;
 
struct TREE{
    int l,r,x;
}tree[N*20];
int rk[N],Tot,rt[N];
void insert(int &o,int l,int r,int data){
    tree[++Tot] = tree[o];
    o = Tot;
    tree[o].x++;
    if(l==r) return ;
    if(mid>=data) insert(tree[o].l,l,mid,data);
    else insert(tree[o].r,mid+1,r,data);
}
int query(int lo,int ro,int l,int r,int h,int t){
    if(l>=h&&r<=t) return tree[ro].x-tree[lo].x;
    int ans = 0;
    if(mid>=h) ans += query(tree[lo].l,tree[ro].l,l,mid,h,t);
    if(mid<t) ans += query(tree[lo].r,tree[ro].r,mid+1,r,h,t);
    return ans;
}
 
void dfs(int u,int f) {
    deep[u] = deep[f]+1;
    son[u] = 0;
    siz[u] = 1;
    fa[u] = f;
    for(int i = 0; i < nxt[u].size(); i++) {
        int v = nxt[u][i];
        int w = len[u][i];
        if(v==f) continue;
        s[v] = w;
        dfs(v,u);
        siz[u] += siz[v];
        if(siz[son[u]]<siz[v]) son[u] = v;
    }
}
void dfs2(int u,int t) {
    id[u] = ++tot;
    ss[id[u]] = s[u];
    top[u] = t;
    if(son[u]) dfs2(son[u],t);
    for(auto v:nxt[u]) {
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}
int Query(int u,int v,int x) {
    int tu = top[u];
    int tv = top[v];
    int ans = 0;
    while(tu!=tv) {
        if(deep[tu]<deep[tv]) {
            swap(u,v);
            swap(tu,tv);
        }
        ans += query(rt[id[tu]-1],rt[id[u]],1,SIZ,1,x);
        u = fa[tu];
        tu = top[u];
    }
    if(u==v) return ans;
    if(id[u]>id[v]) swap(u,v);
    ans += query(rt[id[u]],rt[id[v]],1,SIZ,1,x);
    return ans;
}
 
struct Q{
    int u, v, w;
}Q[N];
vector<int> k;
int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1; i < n; i++) {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        nxt[u].push_back(v);
        nxt[v].push_back(u);
        len[u].push_back(w);
        len[v].push_back(w);
        k.push_back(w);
    }
    for(int i = 1; i <= m; i++) {
        int u, v, x;
        scanf("%d%d%d",&Q[i].u,&Q[i].v,&Q[i].w);
        k.push_back(Q[i].w);
    }
    sort(all(k));
    k.erase(unique(all(k)),k.end());
    SIZ = k.size()+10;
    dfs(1,0);
    dfs2(1,1);
    rt[0] = 0;
    tree[0].l = tree[0].r = tree[0].x = 0;
    for(int i = 1; i <= n; i++) {
        rt[i] = rt[i-1];
        int x = lower_bound(all(k),ss[i])-k.begin()+1;
        insert(rt[i],1,SIZ,x);
    }
    for(int i = 1; i <= m; i++) {
        int x = lower_bound(all(k),Q[i].w)-k.begin()+1;
        printf("%d\n",Query(Q[i].u,Q[i].v,x));
    }
    return 0;
}
View Code

 

posted @ 2019-04-22 16:48  shuai_hui  阅读(139)  评论(0编辑  收藏  举报