QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#468497#1163. Another Tree Queries ProblemMathew_MiaoWA 123ms12876kbC++237.3kb2024-07-08 21:09:052024-07-08 21:09:06

Judging History

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

  • [2024-07-08 21:09:06]
  • 评测
  • 测评结果:WA
  • 用时:123ms
  • 内存:12876kb
  • [2024-07-08 21:09:05]
  • 提交

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]){
            addi[ls(x)]+=addi[x];
            sum[ls(x)]+=addi[x]*sumi(ls(x));
            addi[rs(x)]+=addi[x];
            sum[rs(x)]+=addi[x]*sumi(rs(x));
            addi[x]=0;
        }
        if(adds[x]){
            adds[ls(x)]+=adds[x];
            sum[ls(x)]+=adds[x]*sums(ls(x));
            adds[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);
    }
    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_siz(ql,qr,val,ls(x));
        modify_siz(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[Lca],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;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 12876kb

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: 123ms
memory: 11628kb

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:

826
908
813
1785
2288
1320
3038
2403
4809
3933
4123
3791
5819
4597
6632
7523
4562
8021
7393
9809
7647
6024
11272
7024
12979
14995
9349
9115
8437
11003
18272
22174
16139
17660
11063
14291
12045
18630
12368
17355
23696
20714
24792
20021
13962
22060
13163
19488
13321
25000
19336
30022
19846
33622
17483...

result:

wrong answer 440th numbers differ - expected: '155817', found: '155585'