0pts 玄关求条
查看原帖
0pts 玄关求条
572228
WangSiHan_2011楼主2024/11/21 11:55

全WA,hack也WA,样例过了,求错误小数据

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 100002;

int n,m;
int tid;
int a[MAXN];
int fa[MAXN];
int dep[MAXN];
int siz[MAXN];
int son[MAXN];
int dfn[MAXN];
int rnk[MAXN];
int top[MAXN];
vector <int> links[MAXN];

void Dfs1(int u,int father)
{
    siz[u] = 1;
    fa[u] = father;
    dep[u] = dep[father] + 1;

    auto &link = links[u];
    for(auto v : link)
    {
        if(v == father)
            continue;
        Dfs1(v,u);

        siz[u] += siz[v];
        if(siz[v] > siz[son[u]])
            son[u] = v;
    }
}

void Dfs2(int u,int topp)
{
    top[u] = topp;
    dfn[u] = ++tid;
    rnk[tid] = u;

    if(son[u] == 0)
        return;
    Dfs2(son[u],topp);

    auto &link = links[u];
    for(auto v : link)
    {
        if(v == fa[u] || v == son[u])
            continue;
        Dfs2(v,v);
    }
}

struct TreeNode
{
    int l,r;
    int lv,rv;
    int cnt;
    int lazy;
};

TreeNode stree[MAXN * 4];
void SetLazy(int idx,int v)
{
    TreeNode &cur = stree[idx];
    cur.lv = cur.rv = v;
    if(cur.l != cur.r)
        cur.lazy = v;
}

void PushUp(int idx)
{
    TreeNode &cur = stree[idx];
    TreeNode &left = stree[idx * 2];
    TreeNode &right = stree[idx * 2 + 1];
    cur.lv = left.lv;
    cur.rv = right.rv;
    cur.cnt = left.cnt + right.cnt;
    if(left.rv == right.lv)
        cur.cnt--;
}

void PushDown(int idx)
{
    TreeNode &cur = stree[idx];
    if(cur.lazy)
    {
        SetLazy(idx * 2,cur.lazy);
        SetLazy(idx * 2 + 1,cur.lazy);
        cur.lazy = 0;
    }
}

void BuildTree(int idx,int l,int r)
{
    TreeNode &cur = stree[idx];
    cur.l = l;
    cur.r = r;
    if(l == r)
    {
        cur.lv = cur.rv = a[rnk[l]];
        cur.cnt = 1;
        return;
    }

    int mid = (cur.l + cur.r) / 2;
    BuildTree(idx * 2,l,mid);
    BuildTree(idx * 2 + 1,mid + 1,r);
    PushUp(idx);
}

void Change_Tree(int idx,int l,int r,int v)
{
    TreeNode &cur = stree[idx];
    if(l <= cur.l && cur.r <= r)
    {
        SetLazy(idx,v);
        return;
    }

    PushDown(idx);
    int mid = (cur.l + cur.r) / 2;
    if(l <= mid)
        Change_Tree(idx * 2,l,r,v);
    if(mid + 1 <= r)
        Change_Tree(idx * 2 + 1,l,r,v);
    PushUp(idx);
}

struct Pos
{
    int lv,rv;
    int cnt;
};

Pos Query_Tree(int idx,int l,int r)
{
    TreeNode &cur = stree[idx];
    if(l <= cur.l && cur.r <= r)
        return {cur.lv,cur.rv,cur.cnt};
    
    PushDown(idx);
    int mid = (cur.l + cur.r) / 2;
    if(r <= mid)
        return Query_Tree(idx * 2,l,r);
    if(l >= mid + 1)
        return Query_Tree(idx * 2 + 1,l,r);
    
    Pos L = Query_Tree(idx * 2,l,r);
    Pos R = Query_Tree(idx * 2 + 1,l,r);
    Pos res = {L.lv,R.rv,L.cnt + R.cnt};
    if(stree[idx * 2].rv == stree[idx * 2 + 1].lv)
        res.cnt--;
    return res;
}

void Change(int x,int y,int v)
{
    while(top[x] != top[y])
    {
        if(dep[top[x]] > dep[top[y]])
        {
            Change_Tree(1,dfn[top[x]],dfn[x],v);
            x = fa[top[x]];
        }
        else
        {
            Change_Tree(1,dfn[top[y]],dfn[y],v);
            y = fa[top[y]];
        }
    }

    if(dep[x] > dep[y])
        Change_Tree(1,dfn[y],dfn[x],v);
    else
        Change_Tree(1,dfn[x],dfn[y],v);
}

int Query(int x,int y)
{
    int res = 0;
    while(top[x] != top[y])
    {
        if(dep[top[x]] > dep[top[y]])
        {
            Pos tt = Query_Tree(1,dfn[top[x]],dfn[x]);
            res += tt.cnt;
            Pos ttt = Query_Tree(1,dfn[fa[top[x]]],dfn[fa[top[x]]]);
            if(tt.rv == ttt.lv)
                res--;
            x = fa[top[x]];
        }
        else
        {
            Pos tt = Query_Tree(1,dfn[top[y]],dfn[y]);
            res += tt.cnt;
            Pos ttt = Query_Tree(1,dfn[fa[top[y]]],dfn[fa[top[y]]]);
            if(tt.rv == ttt.lv)
                res--;
            y = fa[top[y]];
        }

        //cout << x << " " << y << " " << res << endl;
    }

    if(dep[x] > dep[y])
        res += Query_Tree(1,dfn[y],dfn[x]).cnt;
    else
        res += Query_Tree(1,dfn[x],dfn[y]).cnt;
    return res;
}

void Check_Init()
{
    cout << "dfn: ";
    for(int i = 1;i <= n;i++)
        cout << dfn[i] << " ";
    cout << endl;
    cout << "fa: ";
    for(int i = 1;i <= n;i++)
        cout << fa[i] << " ";
    cout << endl;
    cout << "dep: ";
    for(int i = 1;i <= n;i++)
        cout << dep[i] << " ";
    cout << endl;
    cout << "son: ";
    for(int i = 1;i <= n;i++)
        cout << son[i] << " ";
    cout << endl;
    cout << "top: ";
    for(int i = 1;i <= n;i++)
        cout << top[i] << " ";
    cout << endl;
    cout << "rnk: ";
    for(int i = 1;i <= n;i++)
        cout << rnk[i] << " ";
    cout << endl;
    cout << "siz: ";
    for(int i = 1;i <= n;i++)
        cout << siz[i] << " ";
    cout << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);

    cin >> n >> m;
    for(int i = 1;i <= n;i++)
        cin >> a[i];
    for(int i = 1;i < n;i++)
    {
        int u,v;
        cin >> u >> v;
        links[u].push_back(v);
        links[v].push_back(u);
    }

    Dfs1(1,1);
    Dfs2(1,1);
    BuildTree(1,1,n);
    
    while(m--)
    {
        char type;
        int x,y,v;

        cin >> type >> x >> y;
        if(type == 'C')
        {
            cin >> v;
            Change(x,y,v);
        }
        else
            cout << Query(x,y) << endl;
    }

    return 0;
}

/*
6 10
2 2 1 2 3 2
1 2
1 3
2 4
2 5
2 6
Output:
2
*/
2024/11/21 11:55
加载中...