【悬关】树剖+线段树,小数据自己对拍没问题,只过了样例,WA+TLE求助
查看原帖
【悬关】树剖+线段树,小数据自己对拍没问题,只过了样例,WA+TLE求助
317008
青溪白石楼主2024/1/25 20:38
#include <clocale>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
//const int inf = 1e6+1;
vector<int> G[maxn];
int w[maxn], pa[maxn], son[maxn], siz[maxn], dep[maxn];
int top[maxn], rnk[maxn]/*实->虚*/, dfn[maxn]/*虚->实*/, lst[maxn];
int n, q;
#define ls(x) ((x) << 1)
#define rs(x) (((x) << 1) | 1)
struct Node{
    int l, r;
    int lcol, rcol;
    int cnt;
    //int setcol;
};
int lptr, rptr, lc, rc;
struct Seg{
    Node nodes[maxn*4];
    void expand(int uid){//parent->lson,rson
        Node& u = nodes[uid];
        if(u.l == u.r) return;
        Node& l = nodes[ls(uid)];
        Node& r = nodes[rs(uid)];
        if(u.cnt == 1){
            l.cnt = r.cnt = 1;
            l.lcol = l.rcol = r.rcol = r.lcol = u.lcol;
        }
    }
    void upd(int u){//lson,rson->parent
        if(nodes[u].l == nodes[u].r) return;
        nodes[u].cnt = nodes[ls(u)].cnt + nodes[rs(u)].cnt;
        if(nodes[ls(u)].rcol == nodes[rs(u)].lcol) nodes[u].cnt--;
        nodes[u].lcol = nodes[ls(u)].lcol; nodes[u].rcol = nodes[rs(u)].rcol;
    }
    void build(int l, int r, int uid){
        Node& u = nodes[uid];
        u.l = l, u.r = r;
        if(l == r){
            u.cnt = 1;
            u.lcol = u.rcol = w[dfn[l]];
            return;
        }
        int m = (l+r)>>1;
        build(l, m, ls(uid));
        build(m+1, r, rs(uid));
        upd(uid);
    }
    void set(int t, int l, int r, int uid){
        Node& u = nodes[uid];
        if(l <= u.l && u.r <= r){
            //u.setcol = t;
            u.lcol = u.rcol = t;
            u.cnt = 1;
            return;
        }
        expand(uid);
        if(u.l == u.r) return;
        int m = (u.l + u.r) >> 1;
        if(l <= nodes[ls(uid)].r) set(t, l, r, ls(uid));
        if(r >= nodes[rs(uid)].l) set(t, l, r, rs(uid));
        upd(uid);
    }
    int querycnt(int l, int r, int u){
        {
            if(nodes[u].l == lptr)
                lc = nodes[u].lcol;
            if(nodes[u].r == rptr)
                rc = nodes[u].rcol;
            if(nodes[u].r == lptr)
                lc = nodes[u].rcol;
            if(nodes[u].l == rptr)
                rc = nodes[u].lcol;
        }
        if(nodes[u].l >= l && nodes[u].r <= r) return nodes[u].cnt;
        expand(u);
        int ans = 0, lcol = -1;
        if(nodes[u].l == nodes[u].r){
            return 1;
        }
        if(l <= nodes[ls(u)].r){
            ans = querycnt(l, r, ls(u));
            lcol = nodes[ls(u)].rcol;
        }
        if(r >= nodes[rs(u)].l){
            ans += querycnt(l, r, rs(u));
            if(lcol == nodes[rs(u)].lcol) ans--;
        }
        return ans;
    }
}sgt;
void pre(int u){
    siz[u] = 1;
    son[u] = -1;
    for(int i = 0; i < G[u].size(); i++){
        int v = G[u][i];
        if(v == pa[u]) continue;
        pa[v] = u;
        dep[v] = dep[u]+1;
		pre(v);
        if(son[u] == -1 || siz[v] > siz[son[u]])son[u] = v;
        siz[u] += siz[v]; 
    }
}
int cnt = 0;
void dfs(int u, int tp){
    cnt++;
    rnk[u] = cnt;
    dfn[cnt] = u;
    top[u] = tp;
    lst[u] = cnt;
    if(son[u] != -1){
        dfs(son[u], tp);
    }
    for(int i = 0; i < G[u].size(); i++){
        int v = G[u][i];
        if(v == pa[u] || v == son[u]) continue;
        dfs(v, v);
        //lst[u] = max(lst[u], lst[v]);
    }
}
int query(int x, int y){
    int ans = 0, xcol = -1, ycol = -1;
    while(top[x] != top[y]){
        if(dep[top[x]] > dep[top[y]]){
            lptr = rnk[top[x]], rptr = rnk[x];
            ans += sgt.querycnt(rnk[top[x]], rnk[x], 1);
            if(xcol == rc) ans --;
            xcol = lc;
            x=pa[top[x]];
        }
        else {
            lptr = rnk[top[y]], rptr = rnk[y];
            ans += sgt.querycnt(rnk[top[y]], rnk[y], 1);
            if(ycol == rc) ans --;
            ycol = lc;
            y=pa[top[y]];
        }
    }
    if(dep[x] > dep[y]) {
        swap(x, y);
        swap(xcol, ycol);
    }
    lptr = rnk[x], rptr = rnk[y];
    ans += sgt.querycnt(rnk[x], rnk[y], 1);
    /*if(delta == 1){
        if(lc != xcol && rc != ycol) return ans+1;
        return ans;
    }*/
    //int e = 0;
    if(lc == xcol) ans--;
    if(rc == ycol) ans--;
    return ans;
}
void set(int col, int x, int y){
    while(top[x] != top[y]){
        if(dep[x] > dep[y]){
            sgt.set(col, rnk[top[x]], rnk[x], 1);
            x = pa[top[x]];
        }
        else{
            sgt.set(col, rnk[top[y]], rnk[y], 1);
            y = pa[top[y]];
        }
    }
    if(dep[x] != dep[y]){
        if(dep[x] > dep[y]){
            swap(x, y);
        }
        sgt.set(col, rnk[x], rnk[y], 1);
    }
}
int main(){
    //freopen("input.txt", "r", stdin);
    cin >> n >> q;
    //cout << "end cin n and q\n";
    //return 0;
    //cout << n << " " << q << endl;
    for(int i = 1; i <= n; i++)
        cin >> w[i];
    //cout << "end cin colour\n";
    for(int i = 1; i < n; i++){
        int a, b; cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    //cout << "end cin edge";
    pre(1);
    dfs(1, 1);
    //
    /*for(int i = 1; i <= n; i++){
        cout << top[i] << " ";
    }cout << endl;*/
    sgt.build(1, n, 1);
    /*for(int i = 1; i <= n; i++){
        cout << top[i] << " ";
    }cout << endl;*/
    //return 0;
    while(q--){
        string s; cin >> s;
        if(s == "C"){
            int a, b, c;
            cin >> a >> b >> c;
            set(c, a, b);
        }
        if(s == "Q"){
            int a, b;
            cin >> a >> b;
            cout << query(a, b) << endl;
        }
    }
    //system("pause");
    return 0;
}
2024/1/25 20:38
加载中...