社区讨论

萌新刚学 1ms,求调小清新数据结构题

P5399[Ynoi2018] 駄作参与者 7已保存回复 7

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@mjob78g4
此快照首次捕获于
2025/12/27 21:01
2 个月前
此快照最后确认于
2025/12/28 10:20
2 个月前
查看原帖
rt
C
//when you use vector or deque,pay attention to the size of it.
//by OldDriverTree
#include<bits/stdc++.h>
//#include<atcoder/all>
//#include<bits/extc++.h>
#define range(vec) vec.begin(),vec.end()
#define siz(vec) (int)vec.size()
#define tup array<int,3>
#define P pair<int,int>
#define int long long
#define mid (l+r>>1)
using namespace std;
//using namespace atcoder;
//using namespace __gnu_pbds;
//using mint=modint998244353;
const int N=1e5+1,M=501;
int fa[N],Fa[N],dep[N],near[N];
int n,m,B,t,tot,id[N],di[M],Id[N];
int cnt,dfn[N],st[17][N],p[N][2];
vector<vector<int> > h[M][2][2];
vector<int> a,b[N],g[N],dis[N];
vector<P> G[M],f[M][2][2];
P F[M],H[M];

int read() {
    int x=0; bool _=true; char c=0;
    while (!isdigit(c) ) _&=(c!='-'),c=getchar();
    while (isdigit(c) ) x=x*10+(c&15),c=getchar();
    return _?x:-x;
}
namespace cluster
{
    vector<int> p,stk;
    int siz[N],cur[N],awa[N];
    void build(int x,int y) {
        Fa[y]=x,near[x]=x,tot++,di[tot]=y,b[tot].swap(p);
        for (int o=y;o^x;o=fa[o]) near[o]=o;
        for (int o:b[y]) id[o]=tot,!near[o]&&(near[o]=near[fa[o] ]);
        if (!t) t=tot,b[tot].insert(b[tot].begin(),1),id[1]=tot;
    }
    void dfs(int u)
    {
        st[0][dfn[u]=++cnt]=fa[u];
        siz[u]=1,cur[u]=stk.size(); int cnt=0;
        for (int v:g[u]) {
            stk.push_back(v),fa[v]=u,dep[v]=dep[u]+1,dfs(v);
            siz[u]+=siz[v]; if (awa[v]) awa[u]=awa[v],cnt++;
        }
        if (siz[u]>B||cnt>1||u==1)
        {
            siz[u]=1,awa[u]=u,a.push_back(u),cnt=0;
            for (int i=0,now=cur[u],o=0;i<=g[u].size();i++)
            {
                int v=i<g[u].size()?g[u][i]:0;
                if (cnt+siz[v]>B||(o&&awa[v])||!v) {
                    int r=v?cur[v]-1:stk.size();
                    while (now<r) p.push_back(stk[now++]);
                    build(u,o?o:p.back() ),o=cnt=0;
                }
                cnt+=siz[v];
                if (awa[v]) o=awa[v];
            }
            stk.resize(cur[u]);
        }
    }
}
void dfs(int u,int fa,int len,int rt) {
    dis[rt][u^Fa[di[id[rt] ] ]?Id[u]:b[id[rt] ].size()]=len;
    for (int v:g[u]) if (v^fa) dfs(v,u,len+1,rt);
}
int LCA(int x,int y) {
    if (x==y) return x; x=dfn[x],y=dfn[y];
    if (x>y) swap(x,y); int k=__lg(y-x);
    x=st[k][x+1],y=st[k][y-(1<<k)+1];
    return dep[x]<dep[y]?x:y;
}
int Dis(int x,int y) { return dep[x]+dep[y]-2*dep[LCA(x,y)]; }
P operator +(P x,int y) { return {x.first,x.second+y*x.first}; }
P operator +(P x,P y) { return {x.first+y.first,x.second+y.second}; }
P operator -(P x,P y) { return {x.first-y.first,x.second-y.second}; }
int operator *(P x,P y) { return x.first*y.second+x.second*y.first; }
P get(int x,int y,int z) {
    if (z==INT_MAX) return {0,0};
    else if (z>=0) return f[x][y][0][min(z,siz(f[x][y][0])-1)];
    else return f[x][y][1][min(-z-1,siz(f[x][y][1])-1)];
}
int Get(int x,int y,int z) {
    if (y==INT_MAX||z==INT_MAX) return 0;
    int p=0,q=0; if (y<0) p=1,y=-y-1; if (z<0) q=1,z=-z-1;
    y=min(y,siz(h[x][y][z])-1),z=min(z,siz(h[x][y][z][0])-1);
    return h[x][p][q][y][z];
}
void dfs1(int u) {
    F[u]={0,0}; for (auto [v,w]:G[u])
    dfs1(v),F[u]=F[u]+F[v]+get(v,1,p[v][0])+w;
}
void dfs2(int u)
{
    P sum=H[u]; for (auto [v,w]:G[u])
    sum=sum+F[v]+get(v,1,p[v][0])+w;
    for (auto [v,w]:G[u]) {
        P t=F[v]+get(v,1,p[v][0])+w;
        H[v]=sum-t+get(v,0,p[v][0])+w,dfs2(v);
    }
}
main()
{
    n=read(),B=2*sqrt(n);
    for (int i=2;i<=n;i++) g[read()].push_back(i);
    cluster::dfs(1),id[1]=++tot,reverse(a.begin(),a.end() );
    for (int i=1;(1<<i)<=n;i++)
        for (int j=1;j+(1<<i)-1<=n;j++) {
            int x=st[i-1][j],y=st[i-1][j+(1<<i-1)];
            st[i][j]=dep[x]<dep[y]?x:y;
        }
    for (int p=1;p<tot;p++)
    {
        int y=di[p],x=Fa[y]; for (int i=0;i<b[p].size();i++) Id[b[p][i] ]=i;
        for (int o:b[p]) if (o^1) g[fa[o] ].push_back(o),g[o].push_back(fa[o]);
        for (int o:b[p]) {
            dis[o].resize(b[p].size()+1),dfs(o,0,0,o);
            if (p==t) dis[o][0]=dis[o].back();
        }
        for (int o:b[p]) g[o].clear(); g[x].clear();
        int t[2]={Id[y],b[p].size()};
        for (int i:{0,1}) for (int j:{0,1})
        {
            int awa=0; for (int o:b[p])
            awa=max(awa,dis[o][t[j] ]);
            f[p][i][j].resize(awa+1);
            for (int o:b[p]) {
                int x=dis[o][t[j] ],y=dis[o][t[i] ];
                f[p][i][j][x]=f[p][i][j][x]+(P){1,y};
            }
            for (int k=1;k<=awa;k++)
            f[p][i][j][k]=f[p][i][j][k-1]+f[p][i][j-1][k];
        }
        for (int i:{0,1}) for (int j:{0,1})
        {
            int n=f[p][0][i].size(),m=f[p][0][j].size();
            h[p][i][j].resize(n);
            for (int k=0;k<n;k++)
            h[p][i][j][k].resize(m);
            for (int c:b[p]) for (int d:b[p])
            h[p][i][j][dis[c][t[i] ] ][dis[d][t[j] ] ]+=dis[c][Id[d] ];
            for (int c=0;c<n;c++)
                for (int d=1;d<m;d++)
                    h[p][i][j][c][d]+=h[p][i][j][c][d-1];

            for (int c=1;c<n;c++)
                for (int d=0;d<m;d++)
                    h[p][i][j][c][d]+=h[p][i][j][c-1][d];
        }
    }
    for (int i=1;i<tot;i++) {
        int y=di[i],x=Fa[y];
        G[id[x] ].push_back({x,dep[y]-dep[x]});
    }
    m=read();
    while (m--)
    {
        int p0=read(),d0=read(),p1=read(),d1=read(),ans=0;
        for (int i=1;i<tot;i++)
        {
            int y=di[i],x=Fa[y],l,r;
            l=d0-Dis(y,p0),r=d0-Dis(x,p0);
            p[i][0]=l<0&&r<0?INT_MAX:l>r?l:-r-1;
            l=d1-Dis(y,p1),r=d1-Dis(x,p1);
            p[i][1]=l<0&&r<0?INT_MAX:l>r?l:-r-1;
            if (x!=id[p0]&&y!=id[p1]) ans+=Get(i,p[i][0],p[i][1]);
            else
            {
                int c0,c1;
                if (x!=id[p0]) {
                    if (p[i][0]>=0) l=p[i][0],c0=Id[y];
                    else r=-p[i][0]-1,c0=b[i].size();
                }
                else l=d0,c0=Id[p0];
                if (y!=id[p1]) {
                    if (p[i][1]>=0) r=p[i][1],c1=Id[y];
                    else r=-p[i][1]-1,c1=b[i].size();
                }
                else r=d1,c1=Id[p1];
                for (int c:b[i])
                    for (int d:b[i])
                        if (dis[c][c0]<=l&&dis[d][c1]<=r)
                            ans+=dis[c][Id[d] ];
            }
        }
        dfs1(tot),dfs2(tot);
        for (int i=1;i<tot;i++) {
            int x=id[Fa[di[i] ] ];
            ans+=get(i,0,p[i][1])*F[i]+get(i,1,p[i][1])*H[x];
        }
        printf("%lld\n",ans);
    }
    return 0;
}

回复

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

正在加载回复...