QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#468462 | #1163. Another Tree Queries Problem | Mathew_Miao | WA | 131ms | 15936kb | C++23 | 7.3kb | 2024-07-08 20:56:28 | 2024-07-08 20:56:29 |
Judging History
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'