线段树合并

一般是对权值线段树进行操作

直接上代码

hnoi 2016 永无乡

#define MAXN 100010UL
#include <cstdio>
 
using namespace std;
 
int n, m, num, Q, bg[MAXN], fa[MAXN], Rt[MAXN];
 
struct Seg { int ls, rs, val; } bn[20*MAXN];
 
int Get_fa(int x) {
    return fa[x]==x?fa[x]:fa[x] = Get_fa(fa[x]);
}
 
void Insert(int &rt, int l, int r, int pos) {
    if(!rt) rt = ++ num;
    if(l==r) {
        ++ bn[rt].val;
        return;
    }
    int mid = (l+r)>>1;
    if(pos<=mid) Insert(bn[rt].ls, l, mid, pos);
    else Insert(bn[rt].rs, mid+1, r, pos);
    bn[rt].val = bn[bn[rt].ls].val+bn[bn[rt].rs].val;
    return;
}
 
int Merge(int x, int y, int l, int r) {
    if(x==0||y==0) return x+y;
    if(l==r) bn[x].val += bn[y].val;
    else {
        bn[x].val += bn[y].val;
        int mid = (l+r)>>1;
        bn[x].ls = Merge(bn[x].ls, bn[y].ls, l, mid);
        bn[x].rs = Merge(bn[x].rs, bn[y].rs, mid+1, r);
    }
    return x;
}
 
int Ask(int rt, int l, int r, int k) {
    if(l==r) return l;
    int mid = (l+r)>>1;
    if(bn[bn[rt].ls].val>=k) return Ask(bn[rt].ls, l, mid, k);
    else return Ask(bn[rt].rs, mid+1, r, k-bn[bn[rt].ls].val);
}
 
int main() {
    int x, y;
    char s[10];
    scanf("%d%d", &n, &m);
    for(int i = 1 ; i <= n ; ++ i) {
        scanf("%d", &x), Insert(Rt[i], 1, n, x);
        bg[x] = i, fa[i] = i;
    }
    for(int i = 1 ; i <= m ; ++ i) {
        scanf("%d%d", &x, &y);
        x = Get_fa(x), y = Get_fa(y);
        if(x!=y) fa[y] = x, Rt[x] = Merge(Rt[x], Rt[y], 1, n);
    }
    scanf("%d", &Q);
    for(int i = 1 ; i <= Q ; ++ i) {
        scanf("%s%d%d", s, &x, &y);
        if(*s=='B') {
            x = Get_fa(x), y = Get_fa(y);
            if(x!=y) fa[y] = x, Rt[x] = Merge(Rt[x], Rt[y], 1, n);
        } else {
            x = Get_fa(x);
            if(bn[Rt[x]].val<y) puts("-1");
            else printf("%d\n", bg[Ask(Rt[x], 1, n, y)]);
        }
    }
    //while(1);
    return 0;
}

二叉树

#define MAXN 5000010UL
#include <cstdio>
#include <algorithm>
 
using namespace std;
 
typedef long long ll;
 
int n, tot, num, w[MAXN], lc[MAXN], rc[MAXN], Rt[400010];
ll ret, cnt, ans;
 
int Merge(int x, int y, int l, int r) {
    if(w[x]==0||w[y]==0) {
        if(w[x]||w[y]) {
            if(w[x]==0) ret += w[y]*cnt;
            else cnt += w[x];
        }
        return x+y;
    }
    w[x] += w[y];
    int mid = (l+r)>>1;
    lc[x] = Merge(lc[x], lc[y], l, mid);
    rc[x] = Merge(rc[x], rc[y], mid+1, r);
    return x;
}
 
void Insert(int &rt, int l, int r, int pos) {
    rt = ++ tot;
    w[rt] = 1;
    if(l==r) return;
    int mid = (l+r)>>1;
    if(pos<=mid) Insert(lc[rt], l, mid, pos);
    else Insert(rc[rt], mid+1, r, pos);
    return;
}
 
int Dfs(int x) {
    int nw;
    scanf("%d", &nw);
    if(nw>0) {
        Insert(Rt[x], 1, n, nw);
        return 1;
    }
    int ls, rs;
    int size_l = Dfs(ls = ++ num);
    Rt[x] = Rt[ls];
    int size_r = Dfs(rs = ++ num);
    ret = cnt = 0;
    Rt[x] = Merge(Rt[x], Rt[rs], 1, n);
    ans += min(ret, 1ll*size_l*size_r-ret);
    return size_l+size_r;
}
 
int main() {
    scanf("%d", &n);
    Dfs(0);
    printf("%lld", ans);
    return 0;
}

雨天的尾巴

 
#define MAXN 100010UL
#include <cstring>
#include <vector>
#include <cstdio>
#include <algorithm>
 
using namespace std;
 
int n, m, t, tot, num, Ans[MAXN], shu[MAXN], q[MAXN<<1][3], fa[MAXN][20], sn[MAXN], d[MAXN], Rt[MAXN];
 
vector <int> v1[MAXN];
vector <int> v2[MAXN];
 
struct ME {
    int zhi, id;
    friend bool operator < (ME x, ME y) {
        return x.zhi<y.zhi;
    }
}st[MAXN<<1];
 
struct Seg { int ls, rs, mx, frm; } bn[5000010];
 
struct Edge { int hou, nt; } sg[MAXN<<1];
 
void Add(int x, int y) {
    sg[t] = (Edge){y, d[x]}, d[x] = t ++;
    sg[t] = (Edge){x, d[y]}, d[y] = t ++;
    return;
}
 
void Dfs_1(int x, int _fa, int dep) {
    fa[x][0] = _fa, sn[x] = dep;
    for(int i = 1 ; (1<<i) <= sn[x] ; ++ i) fa[x][i] = fa[fa[x][i-1]][i-1];
    for(int i = d[x] ; i != -1 ; i = sg[i].nt) if(sg[i].hou!=_fa) Dfs_1(sg[i].hou, x, dep+1);
    return;
}
 
int Get_lca(int &x, int &y) {
    if(sn[x]<sn[y]) swap(x, y);
    int lg = 0;
    while((1<<lg+1)<=sn[x]) ++ lg;
    for(int i = lg ; i >= 0 ; -- i) if(sn[fa[x][i]]>=sn[y]) x = fa[x][i];
    if(x==y) return x;
    for(int i = lg ; i >= 0 ; -- i) if(fa[x][i]!=fa[y][i]) x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}
 
void Update(int rt) {
    bn[rt].mx = bn[bn[rt].ls].mx, bn[rt].frm = bn[bn[rt].ls].frm;
    if(bn[bn[rt].rs].mx>bn[rt].mx) bn[rt].mx = bn[bn[rt].rs].mx, bn[rt].frm = bn[bn[rt].rs].frm;
    return;
}
 
void Insert(int &rt, int l, int r, int pos, int k) {
    if(!rt) rt = ++ tot;
    if(l==r) {
        bn[rt].mx += k, bn[rt].frm = l;
        return;
    }
    int mid = (l+r)>>1;
    if(pos<=mid) Insert(bn[rt].ls, l, mid, pos, k);
    else Insert(bn[rt].rs, mid+1, r, pos, k);
    Update(rt);
    return;
}
 
int Merge(int x, int y, int l, int r) {
    if(x==0||y==0) return x+y;
    if(l==r) bn[x].mx += bn[y].mx, bn[x].frm = l;
    else {
        int mid = (l+r)>>1;
        bn[x].ls = Merge(bn[x].ls, bn[y].ls, l, mid);
        bn[x].rs = Merge(bn[x].rs, bn[y].rs, mid+1, r);
        Update(x);
    }
    return x;
}
 
void Dfs_2(int x, int _fa) {
    for(int i = d[x] ; i != -1 ; i = sg[i].nt) {
        if(sg[i].hou==_fa) continue;
        Dfs_2(sg[i].hou, x);
        Rt[x] = Merge(Rt[x], Rt[sg[i].hou], 1, num);
    }
    for(int i = 0, r = v1[x].size() ; i < r ; ++ i) Insert(Rt[x], 1, num, q[v1[x][i]][2], 1);
    if(bn[Rt[x]].mx>0) Ans[x] = shu[bn[Rt[x]].frm];
    for(int i = 0, r = v2[x].size() ; i < r ; ++ i) Insert(Rt[x], 1, num, q[v2[x][i]][2], -1);
    return;
}
 
int main() {
  //  freopen("ts.in", "r", stdin);
//  freopen("tail.out", "w", stdout);
    memset(d, -1, sizeof(d));
    int x, y, z;
    scanf("%d%d", &n, &m);
    for(int i = 2 ; i <= n ; ++ i) scanf("%d%d", &x, &y), Add(x, y);
    Dfs_1(1, 0, 1);
    int cnt = m;
    for(int i = 1 ; i <= m ; ++ i) {
        scanf("%d%d%d", &x, &y, &z);
        if(sn[x]<sn[y]) swap(x, y);
        q[i][0] = y, q[i][1] = x;
        st[i].id = i, st[i].zhi = z;
        int anc = Get_lca(x, y);
        if(anc==q[i][0]) continue;
        ++ cnt, q[cnt][0] = anc, q[cnt][1] = q[i][0];
        st[cnt].id = cnt, st[cnt].zhi = z;
        q[i][0] = x;
    }
    sort(st+1, st+cnt+1);
    num = 0;
    for(int i = 1 ; i <= cnt ; ++ i) {
        v1[q[i][1]].push_back(i), v2[q[i][0]].push_back(i);
        if((i==1)||st[i].zhi!=st[i-1].zhi) shu[++ num] = st[i].zhi;
        q[st[i].id][2] = num;
    }
    Dfs_2(1, 0);
    for(int i = 1 ; i <= n ; ++ i) printf("%d\n", Ans[i]);
    //while(1);
    return 0;
}

  

 

posted @ 2016-05-14 11:00  assassain  阅读(193)  评论(0编辑  收藏  举报