社区讨论

20pts,求调

P3313[SDOI2014] 旅行参与者 3已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@m00nxvvv
此快照首次捕获于
2024/08/19 15:17
2 年前
此快照最后确认于
2024/08/19 16:52
2 年前
查看原帖
两个小时搞不出来,对题解拷也拷不明白,就是WA。
求助万能的谷民。
CPP
#include<bits/stdc++.h>
#define int long long
#define ls tree[pos].l
#define rs tree[pos].r
using namespace std;
const int N = 1e5+10;
const int INF = 0x3f3f3f3f;

struct edge{
    int to,nxt;
}e[N<<1];

int n , q , edges , cnt ,a[N],c[N],root[N],tot, rk[N], last[N],father[N],siz[N],dfn[N],top[N],deep[N],son[N];
// root 为每个信仰的线段树的根
struct node{ //动态开点
    int sum,maxx,l,r;
}tree[N*15];

void build(int x,int y){
    e[++edges] = {y,last[x]};
    last[x] = edges;
}

void dfs1(int x,int fa){ //树剖板子
    deep[x] = deep[fa] + 1;
    father[x] = fa;
    siz[x] = 1;
    for(int i = last[x]; i; i = e[i].nxt){
        int t = e[i].to;
        if(t == fa) continue;
        dfs1(t,x);
        siz[x] += siz[t];
        if(siz[t] > siz[son[x]]) son[x] = t;
    }
}

void dfs2(int x,int tp){
    dfn[x] = ++ cnt;
    rk[cnt] = x;
    top[x] = tp;
    if(son[x]) dfs2(son[x],tp);
    for(int i = last[x]; i; i = e[i].nxt){
        int t = e[i].to;
        if(t == father[x] || t == son[x]) continue;
        dfs2(t,t);
    }
}

void pushup(int pos){
    tree[pos].sum = tree[ls].sum + tree[rs].sum;
    tree[pos].maxx = max(tree[ls].maxx , tree[rs].maxx);
}

void update(int &pos,int l,int r,int x, int val){
    if(!pos) pos = ++tot;
    if(l == r){
        tree[pos].sum = tree[pos].maxx = val;
        return;
    }
    int mid = (l + r) >> 1;
    if(x <= mid) update(ls,l,mid,x,val);
    else update(rs,mid+1,r,x,val);
    pushup(pos);
}
void clear(int &pos,int l,int r,int x){ //清除线段树
    if(l == r){
        tree[pos] = {0,0,0,0},pos = 0;
        return;
    }
    int mid = (l + r) >> 1;
    if(x <= mid) clear(ls,l,mid,x);
    else clear(rs,mid+1,r,x);
    pushup(pos);
    if(!ls && !rs) tree[pos] = {0,0,0,0},pos = 0;
}

int querysum(int pos,int l,int r,int x,int y){
    if(!pos) return 0;
    if(x <= l && r <= y) return tree[pos].sum;
    int mid = (l + r) >> 1,res = 0;
    if(x <= mid) res += querysum(ls,l,mid,x,y);
    if(mid < y) res += querysum(rs,mid+1,r,x,y);
    return res;
}

int querymax(int pos,int l,int r,int x,int y){
    if(!pos) return 0;
    if(x <= l && r <= y) return tree[pos].maxx;
    int mid = (l + r) >> 1,res = -INF;
    if(x <= mid) res = max(res,querymax(ls,l,mid,x,y));
    if(mid < y) res = max(res,querymax(rs,mid+1,r,x,y));
    return res;
}

void change1(int x,int val){
    clear(root[c[x]],1,n,dfn[x]);
    c[x] = val;
    update(root[c[x]],1,n,dfn[x],a[x]);
}

void change2(int x,int val){ 
    a[x] = val;
    update(root[c[x]],1,n,dfn[x],a[x]);
}

int askmax(int x,int y){
    int res = 0;
    while(top[x] != top[y]){
        if(deep[top[x]] < deep[top[y]])swap(x,y);
        res = max(res,querymax(root[c[x]],1,n,dfn[top[x]],dfn[x]));
        x = father[top[x]];
    }
    if(deep[x] > deep[y]) swap(x,y);
    res = max(res,querymax(root[c[x]],1,n,dfn[x],dfn[y]));
    return res;
}

int asksum(int x,int y){
    int res = 0;
    while(top[x] != top[y]){
        if(deep[top[x]] < deep[top[y]])swap(x,y);
        res += querysum(root[c[x]],1,n,dfn[top[x]],dfn[x]);
        x = father[top[x]];
    }
    if(deep[x] > deep[y]) swap(x,y);
    res += querysum(root[c[x]],1,n,dfn[x],dfn[y]);
    return res;
}

signed main(){
    scanf("%lld%lld",&n,&q);
    for(int i = 1; i <= n; i++)
        scanf("%lld%lld",&a[i],&c[i]);
    for(int i = 1; i < n; i++){
        int x, y;
        scanf("%lld%lld",&x,&y);
        build(x,y);
        build(y,x);
    }
    dfs1(1,0);
    dfs2(1,1);
    for(int i = 1; i <= n; i++)
        update(root[c[i]],1,n,dfn[i],a[i]);
    while(q--){
        char s[10];
        int x , y, d;
        scanf("%s%lld%lld",s,&x,&y);
        if(s[0] == 'C' && s[1] == 'C') change1(x,y);
        if(s[0] == 'C' && s[1] == 'W') change2(x,y);
        if(s[0] == 'Q' && s[1] == 'S') printf("%lld\n",asksum(x,y));
        if(s[0] == 'Q' && s[1] == 'M') printf("%lld\n",askmax(x,y)); 
    }
    return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...