30pts过hack线段树+树剖求助(马蜂良好
查看原帖
30pts过hack线段树+树剖求助(马蜂良好
304558
TheShuMo楼主2024/1/25 21:13
#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define mp make_pair
namespace IO {
    #define int long long 
    #define gh getchar
    inline int read(){char ch=gh();int x=0;bool t=0;while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();return t?-x:x;}
    inline char getc(){char ch=gh();while(ch<'a'||ch>'z') ch=gh();return ch;}
    inline void write(int x){if(x < 0){putchar('-');x = -x;}if(x > 9){write(x / 10);}putchar((x % 10 + '0'));}
}
using namespace IO;
using namespace std;
const int Maxn = 100010;
int a[Maxn], dfn[Maxn], rdfn[Maxn], num, top[Maxn], wc[Maxn], sz[Maxn];
int fa[Maxn];vector<int> G[Maxn]; int dep[Maxn];
int ls, rs;
void dfs(int u, int f){
    fa[u] = f; sz[u] = 1; dep[u] = dep[f] + 1;
    for(auto v : G[u]){
        if(v == f) continue;
        dfs(v,u);
        sz[u] += sz[v];
        if(sz[v] > sz[wc[u]]) wc[u] = v;
    }
}
void dfs2(int u, int tp){
    top[u] = tp; dfn[u] = ++num; rdfn[num] = u;
    if(wc[u]) dfs2(wc[u],tp);
    for(auto v : G[u]){
        if(v != wc[u] and v != fa[u]){
            dfs2(v,v);
        }
    }
}
#define ls(u) u << 1
#define rs(u) u << 1 | 1
int n, m;
struct Node{
    int lf, rt, cnt;
    int l, r;
    int tag;
}t[Maxn << 2];
void push_up(int u){t[u].cnt = t[ls(u)].cnt + t[rs(u)].cnt;
    if(t[ls(u)].rt == t[rs(u)].lf) t[u].cnt--;
    t[u].lf = t[ls(u)].lf; t[u].rt = t[rs(u)].rt;
}
void build(int u, int l, int r){
    t[u].tag = 0;t[u].l = l; t[u].r = r; 
    if(l == r){
        t[u].cnt = 1;
        t[u].lf = t[u].rt = a[rdfn[l]]; return ;
    }int mid = (l + r) >> 1;
    build(ls(u), l, mid);
    build(rs(u),mid+1,r);
    push_up(u);
}
void push_down(int u){
    if(t[u].tag){
        t[rs(u)].tag = t[ls(u)].tag = t[u].tag;
        t[rs(u)].lf = t[rs(u)].rt = t[ls(u)].lf = t[ls(u)].rt = t[u].tag;
        t[rs(u)].cnt = t[ls(u)].cnt = 1; t[u].tag = 0;
    }
}
void update(int u, int l, int r, int L, int R, int d){
    if(L <= l and r <= R) {
        t[u].lf = t[u].rt = d; t[u].tag = d; t[u].cnt = 1;
        return;
    }int mid = (l + r) >> 1;
    push_down(u);
    if(L <= mid) update(ls(u), l, mid, L, R, d);
    if(mid < R) update(rs(u), mid+1,r, L, R, d);
    push_up(u);
}
int query(int u, int l, int r, int L, int R){
    if(l == L) ls = t[u].lf;
    if(r == R) rs = t[u].rt;
    if(L <= l and r <= R){
        return t[u].cnt;
    }int mid = (l + r) >> 1, ans = 0, k = 0,p = 0;
    push_down(u);
    if(R <= mid)return query(ls(u),l,mid,L,R);
    if(L > mid) return query(rs(u),mid+1,r,L,R);
    if(t[ls(u)].rt == t[rs(u)].lf){
        ans = query(ls(u),l,mid,L,R) + query(rs(u),mid+1,r,L,R) - 1;
    }else ans = query(ls(u),l,mid,L,R) + query(rs(u),mid+1,r,L,R);
    return ans;
}
int qry(int x, int y){
    int ans = 0, lf1 = 0, lf2 = 0;
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x,y); swap(lf1,lf2); 
        ans += query(1,1,n,dfn[top[x]],dfn[x]); 
        if(lf1 == rs)ans--; lf1 = ls; 
        x = fa[top[x]]; 
    }
    if(dfn[x] > dfn[y]){
        swap(x,y); swap(lf1,lf2);
    }
    ans += query(1,1,n,dfn[x],dfn[y]);
    if(ls == lf1) ans--;
    if(rs == lf2) ans--;
    return ans;
}
void upd(int x, int y, int d){
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        update(1,1,n,dfn[top[x]],dfn[x],d);
        x = fa[top[x]];
    }if(dfn[x] > dfn[y]) swap(x,y);
    update(1,1,n,dfn[x],dfn[y],d);
}
signed main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1,u,v; i < n; i++){
        cin >> u >> v;
        G[u].pb(v); G[v].pb(u);
    }
    dfs(1, 1); dfs2(1,1); build(1,1,n);
    char op;
    for(int i = 1,x,y,z; i <= m; i++){
        cin >> op;
        if(op == 'C'){ x=read(),y=read(),z=read();
            upd(x,y,z);
        }
        else { cin >> x >> y;
            cout << qry(x,y) << endl;
        }
    }
}
2024/1/25 21:13
加载中...