为什么跑第一个点要2.6秒数据是40000,第二个点100000的数据就0.3秒
查看原帖
为什么跑第一个点要2.6秒数据是40000,第二个点100000的数据就0.3秒
383951
Sora_skyline楼主2021/11/5 19:47
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int MAXN = 1e5+ 10;
int read(){
	int ans=0,w=1;char c=getchar();
	while(c!='-'&&!isdigit(c))c=getchar();
	if(c=='-')w=-1,c=getchar();
	while(isdigit(c))ans=ans*10+c-'0',c=getchar();
	return ans*w;
}
struct {
    int lc, rc;
    int cnt ;
}tr[N <<5];
int tot;
int len;
int res ;
int update(int now, int L,int R, int x, int k)
{
    int p = ++tot;
    tr[p] = tr[now];
    if(L == R){
        tr[p].cnt += k;
        return p;
    }
    int mid = L + R >>1;
    if(mid >= x)tr[p].lc = update(tr[now].lc, L, mid , x, k);
    else tr[p].rc = update(tr[now].rc, mid + 1, R , x, k);
    tr[p].cnt = tr[tr[p].lc].cnt + tr[tr[p].rc].cnt;
    return p;
}
int query(int u, int v, int lca, int fa_lca, int L, int R, int k)
{
    res ++;
    int mid = L + R >> 1;
    int res = tr[tr[u].lc].cnt + tr[tr[v].lc].cnt - tr[tr[lca].lc].cnt - tr[tr[fa_lca].lc].cnt;
    if(L == R)return L;
    if(res >= k) return query(tr[u].lc, tr[v].lc,tr[lca].lc,tr[fa_lca].lc, L, mid , k);
    else return query(tr[u].rc, tr[v].rc,tr[lca].rc,tr[fa_lca].rc, mid + 1, R, k - res);
}
int e[N * 2], ne[N * 2], h[N], idx;
int w[N], root[N];
void add(int a, int b)
{
    e[idx] = b;
    ne[idx ] = h[a];
    h[a] = idx++;
}
int dfn[N], sz[N], top[N], son[N],fa[N],deep[N];
int cnt;
void dfs1(int x, int pre, int depth)
{
    sz[x] = 1;deep[x] = depth;
    root[x] = update(root[pre], 1, len, w[x], 1);
    for(int i = h[x]; i != -1; i = ne[i])
    {
        int y = e[i];
        if(y == pre)continue;
        dfs1(y, x,depth +1);
        fa[y] = x;
        if(sz[y] > sz[son[x]])son[x] = y;
    }
}
void dfs2(int x, int t)
{
    top[x] = t;
    dfn[x] = ++cnt;
    if(!son[x])return;
    dfs2(son[x], t);
    for(int i = h[x]; i != -1; i = ne[i])
    {
        int y = e[i];
        if(y == fa[x] ||y == son[x])continue;
        dfs2(y, y);
    }
}
int lca(int x, int y)
{
    while(top[x] != top[y])
    {
        if(deep[top[x]] < deep[top[y]])swap(x, y);
        x = fa[top[x]];
    }
    if(deep[x] > deep[y])return y;
    else return x;
}

int a[N];
int main(){
    freopen("P2633_1.in", "r", stdin);
    freopen("out.txt", "w", stdout);
    int n, m;
    n = read(), m = read();
    memset(h, -1, sizeof h);
    for(int i = 1; i<= n; i++){
        w[i]= read();
        a[i] = w[i];
    }
    for(int i = 1; i < n; i++)
    {
        int a, b;
        a = read(), b =read();
        add(a, b);
        add(b, a);
    }
    sort(a + 1, a + n + 1);
    len = unique(a + 1, a + n + 1) - a- 1;
    for(int i = 1; i <= n; i++)
        w[i] = lower_bound(a + 1, a + 1 + len, w[i]) - a;
    dfs1(1, 0, 1);
    dfs2(1, 1);
    int last = 0;
    for(int i = 1; i <= m; i++)
    {
        int u, v, k;
        u = read(), v =read(), k = read();
        u ^= last;
        int t = lca(u, v);
        last = query(root[u], root[v], root[t],root[fa[t]], 1, len, k);
        last = a[last];
        printf("%d\n", last);
    }

}
2021/11/5 19:47
加载中...