水题求救

P4114 Qtree1

lzyzs @ 2023-11-16 18:18:09

https://www.luogu.com.cn/record/135397522

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
int deg[N],maxlen[N],maxlenson[N],id[N],v[N],ftop[N],faa[N],fid[N];
int ind,cnt;
vector<int> ma[N];

void dfs(int u,int fa)
{
    faa[u]=fa;
    deg[u]=deg[fa]+1;
    for(int i=0;i<ma[u].size();i++)
    {
        if(ma[u][i]==fa) continue;
        dfs(ma[u][i],u);
        if(maxlen[u]<maxlen[ma[u][i]])
        {
            maxlen[u]=maxlen[ma[u][i]];
            maxlenson[u]=ma[u][i];
        }
    }
    maxlen[u]++;
}

void dfs2(int u,int fa)
{
    id[u]=++ind;
    fid[ind]=u;
    if(maxlenson[u])
    {
        ftop[maxlenson[u]]=ftop[u];
        dfs2(maxlenson[u],u);
    }
    for(int i=0;i<ma[u].size();i++)
    {
        if(ma[u][i]==fa||ma[u][i]==maxlenson[u]) continue;
        ftop[ma[u][i]]=ma[u][i];
        dfs2(ma[u][i],u);
    }
}

class segment_tree{
public:
    struct tree{
        int l,r,maxx;
        void clear(){ l=r=maxx=0;}
    };

    vector<tree> tr;

    segment_tree(int l,int r){
        tree temp;
        temp.clear();
        tr.resize(N*4,temp);
        build(1,l,r);
    }

    void pushup(int k){tr[k].maxx=max(tr[k<<1].maxx,tr[k<<1|1].maxx);}

    void build(int k,int l,int r)
    {
        tr[k].l=l,tr[k].r=r;
        if(l==r) return void(tr[k].maxx=v[fid[l]]);
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        pushup(k);
    }

    void change(int k,int pos,int index)
    {
        if(tr[k].l==tr[k].r) return void(tr[k].maxx=pos);
        int mid=(tr[k].l+tr[k].r)>>1;
        if(index<=mid) change(k<<1,pos,index);
        else if(mid<index) change(k<<1|1,pos,index);
        pushup(k);
    } 

    int query(int k,int l,int r)
    {
        if(l<=tr[k].l&&tr[k].r<=r) return tr[k].maxx;
        int mid=(tr[k].l+tr[k].r)>>1,res=0;
        if(l<=mid) res=max(res,query(k<<1,l,r));
        if(mid<r) res=max(res,query(k<<1|1,l,r));
        return res;
    }
};
signed main()
{
    cin >> n;
//  for(int i=1;i<=n;i++) v[i]=-2e9;
    for(int i=1;i<n;i++)
    {
        int x,y,z;
        cin >> x >> y >> z;
        v[n+i]=z;
        ma[x].push_back(n+i);
        ma[y].push_back(n+i);
        ma[n+i].push_back(x);
        ma[n+i].push_back(y);
    }
    ftop[1]=1;
    dfs(1,0);
    dfs2(1,0);
    segment_tree tree(1,n+n-1);
//  for(int i=1;i<=n+n-1;i++) printf("%d ",id[i]); 
//  printf("\n");
//  for(int i=1;i<=n+n-1;i++) printf("%d ",fid[i]);  
//  printf("\n");
//  build(1,1,ind);

    while(1)
    {
        string opt;
        cin >> opt;
        if(opt=="DONE") break;
        int x,y;
        cin >> x >> y;
        if(opt=="QUERY")
        {
            int res=0;
            while(ftop[x]!=ftop[y])
            {
                if(deg[x]<deg[y]) swap(x,y);
                res=max(tree.query(1,id[ftop[x]],id[x]),res);
                x=faa[ftop[x]];
//              cout << x << ' ' << y << '\n'; 
            }
            if(deg[x]<deg[y]) swap(x,y);
            res=max(tree.query(1,id[y]+1,id[x]),res);
            cout << res << '\n';
        }
        else tree.change(1,y,id[x+n]);
    }
    return 0;
}
/*
4
1 2 1
2 3 2
1 4 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE
*/

by wujingfey @ 2023-11-17 15:19:03

代码和我写法差别太大了看的不是很懂,但是盲猜是把 LCA 的权值也算进去了。因为我就是这样挂成 20pts 的。把边权转化成深度更深的点权后,LCA 的点权不应该给查询贡献。不清楚是不是这个的问题 @lzyzs


by lzyzs @ 2023-11-17 15:56:02

@wujingfey 虽然不是但是感谢,我的写法是把边化为一个点,边权为点权

然后挂在了query的时候


by lzyzs @ 2023-11-17 15:57:20

@wujingfey if(deg[x]<deg[y]) swap(x,y);

    if(deg[ftop[x]]<deg[ftop[y]]) swap(x,y);

|