萌新刚学OI0.114514秒,LCA+树上前缀和16pts求助
查看原帖
萌新刚学OI0.114514秒,LCA+树上前缀和16pts求助
399116
LYqwq楼主2022/8/22 09:53
#include <iostream>
using namespace std;
template<typename T=int>
inline T read(){
    T X=0; bool flag=1; char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<1)+(X<<3)+(ch^48),ch=getchar();
    if(flag) return X;
    return ~(X-1);
}

const int N=1e5+5;
struct edge{
    int to,nxt;
}e[N<<1];
int n,m,u,v,l;
char w[N],c;
int head[N],top;
int d[N],p[N][25],ph[N],pg[N];

void add(int u,int v){
    top++;
    e[top].to=v;
    e[top].nxt=head[u];
    head[u]=top;
}

void init(int u,int fa,int de){
    d[u]=de;
    p[u][0]=fa;
    pg[u]=pg[fa]+(w[u]=='G');
    ph[u]=ph[fa]+(w[u]=='H');
    for(int i=1; i<=20; i++)
        p[u][i]=p[p[u][i-1]][i-1];
    for(int i=head[u]; i; i=e[i].nxt){
        int v=e[i].to;
        if(v==fa) continue;
        init(v,u,de+1);
    }
}

int lca(int u,int v){
    if(u>v) swap(u,v);
    for(int i=20; i>=0; i--)
        if(d[p[v][i]]>=d[u])
            v=p[v][i];
    if(u==v) return u;
    for(int i=20; i>=0; i--)
        if(p[u][i]!=p[v][i])
            u=p[u][i],v=p[v][i];
    return p[u][0];
}

int main(){
    n=read(),m=read();
    scanf("%s",w+1);
    for(int i=1; i<n; i++){
        u=read(),v=read();
        add(u,v);
        add(v,u);
    }
    init(1,0,1);
    while(m--){
        u=read(),v=read();
        cin >> c;
        l=lca(u,v);
        putchar('0'+(c=='G'
            ? pg[u]+pg[v]-pg[p[l][0]]-pg[l]>0
            : ph[u]+ph[v]-ph[p[l][0]]-ph[l]>0));
    }
    puts("");
    return 0;
}

QwQ

2022/8/22 09:53
加载中...