QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#468462#1163. Another Tree Queries ProblemMathew_MiaoWA 131ms15936kbC++237.3kb2024-07-08 20:56:282024-07-08 20:56:29

Judging History

你现在查看的是最新测评结果

  • [2024-07-08 20:56:29]
  • 评测
  • 测评结果:WA
  • 用时:131ms
  • 内存:15936kb
  • [2024-07-08 20:56:28]
  • 提交

answer

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<string>
#include<bitset>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
const int N=1e5;
const int INF=0x3f3f3f3f;
const long long LINF=0x3f3f3f3f3f3f3f3f;
int n,q;
basic_string <int> tr[MAXN];
inline void add_edge(int x,int y){
    tr[x].push_back(y);
}
int dfc=0;
int dad[MAXN],dep[MAXN],son[MAXN];
int siz[MAXN],top[MAXN],dfn[MAXN];
int back[MAXN];
long long sumd[MAXN];
void dfs1(int x){
    dep[x]=dep[dad[x]]+1;
    sumd[x]=dep[x];
    siz[x]=1;
    for(int to:tr[x])
    {
        if(to==dad[x]){
            continue;
        }
        dad[to]=x;
        dfs1(to);
        sumd[x]+=sumd[to];
        siz[x]+=siz[to];
        if(siz[to]>siz[son[x]]){
            son[x]=to;
        }
    }
}
void dfs2(int x){
    dfc++;
    dfn[x]=dfc;
    back[dfc]=x;
    if(son[x]){
        top[son[x]]=top[x];
        dfs2(son[x]);
    }
    for(int to:tr[x])
    {
        if(to==dad[x]||to==son[x]){
            continue;
        }
        top[to]=to;
        dfs2(to);
    }
}
inline int lca(int x,int y){
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]){
            swap(x,y);
        }
        x=dad[top[x]];
    }
    if(dep[x]>dep[y]){
        swap(x,y);
    }
    return x;
}
inline int mca(int x,int y){
    while(top[x]^top[y])
    {
        if(dad[top[y]]==x){
            return top[y];
        }
        y=dad[top[y]];
    }
    return son[x];
}
long long sums[MAXN*4];
long long all=0,alld=0;
#define sum_con(l,r) ((l+r)*(r-l+1ll)/2)
namespace segtree{
    int L[MAXN*4],R[MAXN*4];
    long long add[MAXN*4],addi[MAXN*4],adds[MAXN*4];//+1,+i,+siz[i]
    long long sum[MAXN*4];
    #define ls(x) (x<<1)
    #define rs(x) (x<<1|1)
    #define len(x) (R[x]-L[x]+1ll)
    #define sumi(x) sum_con(L[x],R[x])
    #define sums(x) (sums[R[x]]-sums[L[x]-1])
    inline void push_up(int x){
        sum[x]=sum[ls(x)]+sum[rs(x)];
    }
    inline void push_down(int x){
        if(add[x]){
            add[ls(x)]+=add[x];
            sum[ls(x)]+=add[x]*len(ls(x));
            add[rs(x)]+=add[x];
            sum[rs(x)]+=add[x]*len(rs(x));
            add[x]=0;
        }
        if(addi[x]){
            add[ls(x)]+=addi[x];
            sum[ls(x)]+=addi[x]*sumi(ls(x));
            add[rs(x)]+=addi[x];
            sum[rs(x)]+=addi[x]*sumi(rs(x));
            addi[x]=0;
        }
        if(adds[x]){
            add[ls(x)]+=adds[x];
            sum[ls(x)]+=adds[x]*sums(ls(x));
            add[rs(x)]+=adds[x];
            sum[rs(x)]+=adds[x]*sums(rs(x));
            adds[x]=0;
        }
    }
    void build(int l,int r,int x){
        L[x]=l;
        R[x]=r;
        if(l==r){
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,ls(x));
        build(mid+1,r,rs(x));
    }
    inline void build(){
        build(1,n,1);
    }
    inline void print();
    void modify_add(int ql,int qr,int val,int x){
        int l=L[x],r=R[x];
        if(ql<=l&&r<=qr){
            add[x]+=val;
            sum[x]+=val*len(x);
            return ;
        }
        if(qr<l||r<ql){
            return ;
        }
        push_down(x);
        modify_add(ql,qr,val,ls(x));
        modify_add(ql,qr,val,rs(x));
        push_up(x);
    }
    inline void modify_add(int ql,int qr,int val){
        modify_add(ql,qr,val,1);
    }
    void modify_addi(int ql,int qr,int val,int x){
        int l=L[x],r=R[x];
        if(ql<=l&&r<=qr){
            addi[x]+=val;
            sum[x]+=val*sumi(x);
            return ;
        }
        if(qr<l||r<ql){
            return ;
        }
        push_down(x);
        modify_addi(ql,qr,val,ls(x));
        modify_addi(ql,qr,val,rs(x));
        push_up(x);
    }
    inline void modify_addi(int ql,int qr,int val){
        modify_addi(ql,qr,val,1);
    }
    inline void modify_con(int ql,int qr,int l,int r){
        modify_addi(ql,qr,-1);
        modify_add(ql,qr,ql+l);
    }
    void modify_siz(int ql,int qr,int val,int x){
        int l=L[x],r=R[x];
        if(ql<=l&&r<=qr){
            adds[x]+=val;
            sum[x]+=val*sums(x);
            return ;
        }
        if(qr<l||r<ql){
            return ;
        }
        push_down(x);
        modify_add(ql,qr,val,ls(x));
        modify_add(ql,qr,val,rs(x));
        push_up(x);
    }
    inline void modify_siz(int ql,int qr,int val){
        modify_siz(ql,qr,val,1);
    }
    long long query(int ql,int qr,int x){
        int l=L[x],r=R[x];
        if(ql<=l&&r<=qr){
            return sum[x];
        }
        if(qr<l||r<ql){
            return 0;
        }
        push_down(x);
        return query(ql,qr,ls(x))+query(ql,qr,rs(x));
    }
    inline long long query(int ql,int qr){
        return query(ql,qr,1);
    }
}
inline void mdf_add(int x,int val){
    while(x)
    {
        segtree::modify_add(dfn[top[x]],dfn[x],val);
        x=dad[top[x]];
    }
}
inline void mdf_con(int x,int y){
    int now=0;
    while(top[x]^top[y])
    {
        int len=dfn[y]-dfn[top[y]]+1;
        segtree::modify_con(dfn[top[y]],dfn[y],now+len,now+1);
        now+=len;
        y=dad[top[y]];
    }
    int len=dfn[y]-dfn[x]+1;
    segtree::modify_con(dfn[x],dfn[y],now+len,now+1);
}
inline long long qry(int x){
    long long res=0;
    while(x)
    {
        res+=segtree::query(dfn[top[x]],dfn[x]);
        x=dad[top[x]];
    }
    return res;
}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add_edge(x,y);
        add_edge(y,x);
    }
    dfs1(1);
    top[1]=1;
    dfs2(1);
    for(int i=1;i<=n;i++)
    {
        sums[i]=sums[i-1]+siz[back[i]];
    }
    segtree::build();
    scanf("%d",&q);
    while(q--)
    {
        int opt;
        scanf("%d",&opt);
        if(opt==1){
            int rt,x;
            scanf("%d%d",&rt,&x);
            if(dfn[x]<=dfn[rt]&&dfn[rt]<dfn[x]+siz[x]){
                x=mca(x,rt);
                all+=n-siz[x];
                alld+=sumd[1]-sumd[x];
                segtree::modify_siz(1,n,1);
                segtree::modify_siz(dfn[x],dfn[x]+siz[x]-1,-1);
                mdf_add(dad[x],-siz[x]);
            }
            else{
                all+=siz[x];
                alld+=sumd[x];
                segtree::modify_siz(dfn[x],dfn[x]+siz[x]-1,1);
                mdf_add(dad[x],siz[x]);
            }
        }
        if(opt==2){
            int x,y;
            scanf("%d%d",&x,&y);
            int Lca=lca(x,y);
            if(dep[x]>dep[y]){
                swap(x,y);
            }
            all+=dep[x]+dep[y]-2*dep[Lca]+1;
            alld+=sum_con(dep[Lca],dep[x])+sum_con(dep[Lca],dep[y])-dep[Lca];
            if(x==Lca){
                mdf_con(x,y);
            }
            else{
                mdf_con(Lca,x);
                mdf_con(Lca,y);
                segtree::modify_add(dfn[Lca],dfn[Lca],-1);
            }
            mdf_add(dad[x],dep[x]+dep[y]-2*dep[Lca]+1);
        }
        if(opt==3){
            int x;
            scanf("%d",&x);
            printf("%lld\n",dep[x]*all+alld-2*qry(x));
        }
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 12796kb

input:

5
4 2
2 5
1 5
1 3
5
2 2 4
3 4
2 1 5
2 5 5
3 2

output:

1
5

result:

ok 2 number(s): "1 5"

Test #2:

score: -100
Wrong Answer
time: 131ms
memory: 15936kb

input:

200
171 114
50 183
28 68
67 152
139 125
67 55
50 98
106 71
46 42
157 165
42 49
113 12
81 145
105 13
38 96
34 156
24 17
21 191
135 54
174 116
177 157
123 71
95 130
135 193
150 129
25 190
96 93
188 173
90 160
86 187
20 132
199 75
59 195
189 24
40 68
163 83
25 13
73 33
59 50
154 19
146 21
151 67
89 69
...

output:

484
636
417
1461
1558
974
2308
529
2455
1753
3083
3223
3671
3467
5422
4345
3764
6413
595
7061
5625
730
9366
4422
10047
1911
7803
-93
8047
10685
10918
22542
11323
13378
10407
9121
11567
14188
11880
18081
25042
21658
22994
10675
12928
22748
13795
20114
13785
12716
15126
27006
15704
13756
13393
20257
1...

result:

wrong answer 1st numbers differ - expected: '826', found: '484'