树上差分(LCA)

https://ac.nowcoder.com/acm/contest/1057/C

O((n+m)logn)

#include
using namespace std;
#define MAXN 100005
int T;//最大深度
 
int n,m;
int cnt,first[MAXN<<1],nxt[MAXN<<1];
int u[MAXN<<1],v[MAXN<<1];
void add(int a,int b){
    ++cnt;
    nxt[cnt]=first[a];first[a]=cnt;
    u[cnt]=a,v[cnt]=b;
}
 
int deep[MAXN<<1],f[MAXN][30];
 
void bfs(int x) {
    queue que;
    que.push(x);
    deep[x]=1;
     
    while(que.size()) {
        int cur=que.front();
        que.pop();
        for(int i=first[cur];i;i=nxt[i]) {
            int to=v[i];
            if(deep[to])continue;
            deep[to]=deep[cur]+1;
            f[to][0]=cur;
             
            for(int j=1;j<=T;j++){
                f[to][j]=f[f[to][j-1]][j-1];
            }
            que.push(to);
        }
    }
}
  
inline int lca(int x,int y) {
    if(deep[x]>deep[y]) swap(x,y);
    for(int i=T;i>=0;i--) {
        if(deep[f[y][i]]>=deep[x]) y=f[y][i];
    }
    if(x==y) return x;
    for(int i=T;i>=0;i--) {
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    }
    return f[x][0];
}
 
int val[MAXN];
void dfs(int cur,int fa){
    for(int i=first[cur];i;i=nxt[i]){
        int to=v[i];
        if(to==fa)continue;
        dfs(to,cur);
         
        val[cur]+=val[to];
    }
}
 
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i

O(n+m)

#include
using namespace std;
#define MAXN 200010

int edgex[MAXN],edgey[MAXN];
int n,m;
int cnt,first[MAXN<<1],nxt[MAXN<<1];
int u[MAXN<<1],v[MAXN<<1];
void add(int a,int b){
	++cnt;
	nxt[cnt]=first[a];first[a]=cnt;
	u[cnt]=a,v[cnt]=b;
}
vector query[MAXN],query_id[MAXN];
void addQuery(int x,int y,int id){
	query[x].push_back(y),query_id[x].push_back(id);
	query[y].push_back(x),query_id[y].push_back(id);
}

int f[MAXN];
int getf(int x){
	if(x==f[x])return x;
	return f[x]=getf(f[x]);
}
void merge(int a,int b){
	int fa=getf(a),fb=getf(b);
	if(fa!=fb)f[fb]=fa;
}
int vis[MAXN],deep[MAXN],ans[MAXN];
void tarjan(int cur){
	vis[cur]=1;
	for(int i=first[cur];i;i=nxt[i]){
		int to=v[i];
		if(vis[to])continue;
		deep[to]=deep[cur]+1;
		tarjan(to);
		merge(cur,to);
	}
	for(int i=0;i

 

你可能感兴趣的:(树上差分(LCA))