Spoj Query on a tree III

Posted 蒟蒻JHY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spoj Query on a tree III相关的知识,希望对你有一定的参考价值。

题目描述

给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白

有两种操作:

0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)

1 v : 询问1到v的路径上的第一个黑点,若无,输出-1

输入输出格式

输入格式:

 

第一行 N,Q,表示N个点和Q个操作

第二行到第N行N-1条无向边

再之后Q行,每行一个操作"0 i" 或者"1 v" (1 ≤ i, v ≤ N).

 

输出格式:

 

对每个1 v操作输出结果

 

输入输出样例

输入样例#1: 
9 8
1 2
1 3
2 4
2 9
5 9
7 9
8 9
6 8
1 3
0 8
1 6
1 7
0 2
1 9
0 2
1 9 
输出样例#1:
-1
8
-1
2
-1

说明

For 1/3 of the test cases, N=5000, Q=400000.

For 1/3 of the test cases, N=10000, Q=300000.

For 1/3 of the test cases, N=100000, Q=100000.

 

(假装我是在spoj上做的一样hhh)

贼裸的树剖+线段树,,,练手题(今天建模能力为0,全在码模板hhh)

#include<bits/stdc++.h>
#define ll long long
#define maxn 100005
#define pb push_back
using namespace std;
vector<int> g[maxn];
int dfn[maxn],dy[maxn],pos;
int siz[maxn],f[maxn],opt;
int cl[maxn],n,m,son[maxn],dc=0;
int sum[maxn<<2|1],mxp[maxn<<2|1];
int le,ri;

void dfs1(int x,int fa){
    f[x]=fa,siz[x]=1;
    int to;
    for(int i=g[x].size()-1;i>=0;i--){
        to=g[x][i];
        if(to==fa) continue;
        dfs1(to,x),siz[x]+=siz[to];
        if(!son[x]||siz[to]>siz[son[x]]) son[x]=to;
    }
}

void dfs2(int x,int tp){
    dfn[x]=++dc,dy[dc]=x,cl[x]=tp;
    if(son[x]) dfs2(son[x],tp);
    int to;
    for(int i=g[x].size()-1;i>=0;i--){
        to=g[x][i];
        if(to==f[x]||to==son[x]) continue;
        dfs2(to,to);
    }
}

void update(int o,int l,int r){
    if(l==r){
        sum[o]^=1;
        if(sum[o]) mxp[o]=dy[l];
        else mxp[o]=0;
        return;
    }
    
    int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
    if(le<=mid) update(lc,l,mid);
    else update(rc,mid+1,r);
    if(sum[lc]) mxp[o]=mxp[lc];
    else mxp[o]=mxp[rc];
    sum[o]=sum[lc]+sum[rc];
}

int query(int o,int l,int r){
    if(l>=le&&r<=ri) return mxp[o];
    int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1,an=0;
    if(le<=mid) an=query(lc,l,mid);
    if(!an&&ri>mid) an=query(rc,mid+1,r);
    return an;
}

inline void tolt(int x){
    le=dfn[x],update(1,1,n);
}

inline int answer(int x){
    int an=-1,po;
    while(x){
        le=dfn[cl[x]],ri=dfn[x];
        po=query(1,1,n);
        if(po) an=po;
        x=f[cl[x]];
    }
    return an;
}

int main(){
    int uu,vv;
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++){
        scanf("%d%d",&uu,&vv);
        g[uu].pb(vv),g[vv].pb(uu);
    }
    
    dfs1(1,0);
    dfs2(1,1);
    
    while(m--){
        scanf("%d%d",&opt,&pos);
        if(opt) printf("%d\n",answer(pos));
        else tolt(pos);
    }
    
    return 0;
}

 

以上是关于Spoj Query on a tree III的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1803Spoj1487 Query on a tree III DFS序+主席树

Spoj Query on a tree III

BZOJ_1803_Spoj1487 Query on a tree III_主席树+dfs序

BZOJ1803: Spoj1487 Query on a tree III

bzoj 1803: Spoj1487 Query on a tree III(主席树)

[SPOJ-PT07J] Query on tree III (主席树)