求助树剖——全MLE了
查看原帖
求助树剖——全MLE了
401052
Endline楼主2022/1/24 10:48

RT,代码如下

#include<bits/stdc++.h>
#define MAXN 200002
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
int n,m;
int head[MAXN],fr[MAXN],to[MAXN],nxt[MAXN],w[MAXN],cnt;
int siz[MAXN],son[MAXN],top[MAXN],val[MAXN],fa[MAXN],dfn[MAXN],dep[MAXN],num;
int a[MAXN<<2],sum[MAXN<<2],maxx[MAXN<<2],minn[MAXN<<2];
bool tag[MAXN<<2];
void add_edge(int x,int y,int val)
{
    to[++cnt]=y;
    fr[cnt]=x;
    w[cnt]=val;
    nxt[cnt]=head[x];
    head[x]=cnt;
}
void dfs1(int u)
{
    siz[u]=1;
    son[u]=-1;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(v==fa[u])continue;
        fa[v]=u;
        dep[v]=dep[u]+1;
        dfs1(v);
        siz[u]+=siz[v];
        val[v]=w[i];
        if(son[u]==-1||siz[v]>siz[son[u]])son[u]=v;
    }
    return;
}
void dfs2(int u,int topn)
{
    top[u]=topn;
    dfn[u]=++num;
    a[num]=val[u];
    if(son[u]==-1)return;
    dfs2(son[u],topn);
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(v==fa[u]||v==son[u])continue;
        dfs2(v,v);
    }
    return;
}
void push_up(int p)
{
    sum[p]=sum[ls(p)]+sum[rs(p)];
    maxx[p]=max(maxx[ls(p)],maxx[rs(p)]);
    minn[p]=min(minn[ls(p)],minn[rs(p)]);
    return;
}
void push_down(int p)
{
    if(tag[p])
    {
        sum[ls(p)]=-sum[ls(p)];
        swap(minn[ls(p)],maxx[ls(p)]);
        minn[ls(p)]=-minn[ls(p)];
        maxx[ls(p)]=-maxx[ls(p)];
        tag[ls(p)]=tag[p];

        sum[rs(p)]=-sum[rs(p)];
        swap(minn[rs(p)],maxx[rs(p)]);
        minn[rs(p)]=-minn[rs(p)];
        maxx[rs(p)]=-maxx[rs(p)];
        tag[rs(p)]=tag[p];

        tag[p]=false;
    }
    return;
}
void build(int l,int r,int p)
{
    if(l==r)
    {
        sum[p]=maxx[p]=minn[p]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,ls(p));build(mid+1,r,rs(p));
    push_up(p);
    return;
}
void update(int l,int r,int s,int t,int p)
{
    if(s>=l&&t<=r)
    {
        sum[p]=-sum[p];
        swap(minn[p],maxx[p]);
        minn[p]=-minn[p];
        maxx[p]=-maxx[p];
        tag[p]=!tag[p];
        return;
    }
    push_down(p);
    int mid=(s+t)>>1;
    if(mid>=l)update(l,r,s,mid,ls(p));
    if(mid<r)update(l,r,mid+1,t,rs(p));
    push_up(p);
    return;
}
void change(int goal,int s,int t,int p,int k)
{
    if(s==t&&s==goal)
    {
        sum[p]=maxx[p]=minn[p]=k;
        return;
    }
    int mid=(s+t)>>1;
    if(mid>=goal)change(goal,s,mid,ls(p),k);
    if(mid<goal)change(goal,mid+1,t,rs(p),k);
    push_up(p);
    return;
}
int query_sum(int l,int r,int s,int t,int p)
{
    if(s>=l&&t<=r)
        return sum[p];
    push_down(p);
    int mid=(s+t)>>1,res=0;
    if(mid>=l)res+=query_sum(l,r,s,mid,ls(p));
    if(mid<r)res+=query_sum(l,r,mid+1,t,rs(p));
    return res;
}
int query_max(int l,int r,int s,int t,int p)
{
    if(s>=l&&t<=r)
        return maxx[p];
    push_down(p);
    int mid=(s+t)>>1,res=-114514;
    if(mid>=l)res=max(res,query_max(l,r,s,mid,ls(p)));
    if(mid<r)res=max(res,query_max(l,r,mid+1,t,rs(p)));
    return res;
}
int query_min(int l,int r,int s,int t,int p)
{
    if(s>=l&&t<=r)
        return minn[p];
    push_down(p);
    int mid=(s+t)>>1,res=114514;
    if(mid>=l)res=min(res,query_min(l,r,s,mid,ls(p)));
    if(mid<r)res=min(res,query_min(l,r,mid+1,t,rs(p)));
    return res;
}
void upd_range(int u,int v)
{
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        update(dfn[top[u]],dfn[u],1,n,1);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    update(dfn[u]+1,dfn[v],1,n,1);
    return;
}
void change_point(int u,int w)
{
    change(dfn[u],1,n,1,w);
    return;
}
int query_sum_range(int u,int v)
{
    int sum=0;
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        sum+=query_sum(dfn[top[u]],dfn[u],1,n,1);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    sum+=query_sum(dfn[u]+1,dfn[v],1,n,1);
    return sum;
}
int query_max_range(int u,int v)
{
    int res=-114514;
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        res=max(res,query_max(dfn[top[u]],dfn[u],1,n,1));
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    res=max(res,query_max(dfn[u]+1,dfn[v],1,n,1));
    return res;
}
int query_min_range(int u,int v)
{
    int res=114514;
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        res=min(res,query_min(dfn[top[u]],dfn[u],1,n,1));
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    res=min(res,query_min(dfn[u]+1,dfn[v],1,n,1));
    return res;
}
int main()
{
    freopen("P1505.in","r",stdin);
    freopen("P1505.out","w",stdout);
    ios::sync_with_stdio(false);
	cin>>n;
    for(int i=1;i<n;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        add_edge(u+1,v+1,w);add_edge(v+1,u+1,w);
    }
    dfs1(1);
    dfs2(1,1);
    build(1,n,1);
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        string str;
        cin>>str;
        int u,v;
        cin>>u>>v;
        if(str=="C")
        {
            u<<=1;
            int x=fr[u],y=to[u];
            if(dep[x]>dep[y])swap(x,y);
            change_point(y,v);
        }
        if(str=="N")
            upd_range(u+1,v+1);
        if(str=="SUM")
            cout<<query_sum_range(u+1,v+1)<<endl;
        if(str=="MAX")
            cout<<query_max_range(u+1,v+1)<<endl;
        if(str=="MIN")
            cout<<query_min_range(u+1,v+1)<<endl;
    }
    return 0;
}
2022/1/24 10:48
加载中...