如何高效落实科学发展观?
查看原帖
如何高效落实科学发展观?
539211
lzyqwq楼主2023/5/19 20:07

rt,指如何快速实现主席树。

我的代码使用指针实现动态开点,按理说应该比较快且省空间,然而却用了 1s 多,空间用了 88MB

#include<bits/stdc++.h>
#define ls(x) x->lc
#define rs(x) x->rc
#define sum(x) x->sum
using namespace std;
const int N=1e5+5;
int n,m,a[N],la,lsh,rev[N],f[20][N],d[N],lg[N];
set<int>s;
map<int,int>mp;
vector<int>g[N];
struct node{
    int sum;
    node*lc,*rc;
    node(){
        sum=0;
        lc=rc=NULL;
    }
}*rt[N];
void build(node*&x,int l,int r){
    x=new node;
    if(l^r){
        int mid=(l+r)>>1;
        build(ls(x),l,mid);
        build(rs(x),mid+1,r);
    }
}
void insert(node*&x,node*y,int l,int r,int k){
    x=new node;
    sum(x)=sum(y)+1;
    if(l^r){
        int mid=(l+r)>>1;
        if(k<=mid){
            rs(x)=rs(y);
            insert(ls(x),ls(y),l,mid,k);
        }else{
            ls(x)=ls(y);
            insert(rs(x),rs(y),mid+1,r,k);
        }
    }
}
int query(node*x,node*y,node*u,node*v,int l,int r,int k,int ok){
    if(l^r){
        int mid=(l+r)>>1,p=sum(ls(x))+sum(ls(y))-sum(ls(u))-sum(ls(v))+ok;
        if(p>=k){
            return query(ls(x),ls(y),ls(u),ls(v),l,mid,k,ok);
        }
        return query(rs(x),rs(y),rs(u),rs(v),mid+1,r,k,p);
    }
    return l;
}
void dfs(int x,int fa){
    insert(rt[x],rt[fa],1,lsh,a[x]);
    for(int i=1;i<=lg[d[x]];++i){
        f[i][x]=f[i-1][f[i-1][x]];
    }
    for(vector<int>::iterator it=g[x].begin();it!=g[x].end();++it){
        if(*it^fa){
            d[*it]=d[x]+1;
            dfs(*it,f[0][*it]=x);
        }
    }
}
int lca(int x,int y){
    if(d[x]<d[y]){
        swap(x,y);
    }
    while(d[x]^d[y]){
        x=f[lg[d[x]-d[y]]][x];
    }
    if(x^y){
        for(int i=lg[d[x]];~i;--i){
            if(f[i][x]^f[i][y]){
                x=f[i][x];
                y=f[i][y];
            }
        }
        return f[0][x];
    }
    return x;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d",a+i);
        s.insert(a[i]);
        lg[i]=log2(i);
    }
    for(set<int>::iterator it=s.begin();it!=s.end();++it){
        rev[mp[*it]=++lsh]=*it;
    }
    for(int i=1;i<=n;++i){
        a[i]=mp[a[i]];
    }
    build(rt[0],1,lsh);
    for(int i=1,u,v;i^n;++i){
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1,0);
    for(int x,y,k,h;m--;){
        scanf("%d%d%d",&x,&y,&k);
        h=lca(x^=la,y);
        printf("%d\n",la=rev[query(rt[x],rt[y],rt[h],rt[f[0][h]],1,lsh,k,0)]);
    }
}
2023/5/19 20:07
加载中...