QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#468068 | #1163. Another Tree Queries Problem | sandforce | WA | 46ms | 14804kb | C++14 | 5.5kb | 2024-07-08 19:11:02 | 2024-07-08 19:11:02 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define C const
#define R register
#define ll long long
#define lll __int128
#define ull unsigned long long
#define ld long double
#define db double
#define F(name,l,r) for(int name=l;name<=r;name++)
#define RF(name,l,r) for(int name=r;name>=l;name--)
#define W(condition) while(condition)
#define PB push_back
#define PF push_front
#define I iterator
#define V(type) vector< type >
#define P(type1,type2) pair< type1 , type2 >
#define Pint pair<int,int>
#define Pll pair<long long,long long>
#define mp(x,y) make_pair(x,y)
#define Q(type) queue< type >
#define DQ(type) deque< type >
#define S(type) stack< type >
#define DGD(type) priority_queue< type >
#define XGD(type) priority_queue< type ,vector< type >,greater< type > >
#define gc getchar();
#define pc(x) putchar(x)
#define O(x) cout<<x<<'\n';
#define _ck cout<<"lcrtree"<<'\n';
template<typename T> inline void fr(T& num){
num=0;short sign=1;char ch=std::getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')sign=-1;
ch=std::getchar();
}
while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
num=num*sign;
}
template<typename T>inline void fw(T x){
if(x<0)std::putchar('-'),x=-x;
if(x>9)fw(x/10);
std::putchar(x%10+'0');
}
const ll N=262144,notag=LONG_LONG_MIN;
int n,m;
vector<int> tree[N];
int depth[N],die[N],sz[N],zhongez[N],linktop[N],dfn[N],rk[N],cnt,root=1,dsum[N];
struct segment_tree{
struct segnode{
int l,r;
ll a,v,lz;
}t[N<<2];
#define ls(p) p<<1
#define rs(p) p<<1|1
inline void pushdown(int p){
if(t[p].lz){
t[ls(p)].a+=t[p].lz*(t[ls(p)].r-t[ls(p)].l+1);
t[rs(p)].a+=t[p].lz*(t[rs(p)].r-t[rs(p)].l+1);
t[ls(p)].lz+=t[p].lz,t[rs(p)].lz+=t[p].lz;
t[ls(p)].v+=t[p].lz*(dsum[t[ls(p)].r]-dsum[t[ls(p)].l-1]);
t[rs(p)].v+=t[p].lz*(dsum[t[rs(p)].r]-dsum[t[rs(p)].l-1]);
t[p].lz=0;
}
}
inline void pushup(int p){
t[p].a=t[ls(p)].a+t[rs(p)].a;
t[p].v=t[ls(p)].v+t[rs(p)].v;
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r)return;
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void change(int p,int l,int r,int val){
if(l<=t[p].l&&r>=t[p].r)return t[p].lz+=val,t[p].a+=t[p].r-t[p].l+1,t[p].v+=dsum[t[p].r]-dsum[t[p].l-1],void();
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)change(ls(p),l,r,val);
if(r>mid)change(rs(p),l,r,val);
pushup(p);
}
ll getv(int p,int l,int r){
if(l<=t[p].l&&r>=t[p].r)return t[p].v;
pushdown(p);
int mid=(t[p].r+t[p].l)>>1;
ll res=0;
if(l<=mid)res+=getv(ls(p),l,r);
if(r>mid) res+=getv(rs(p),l,r);
return res;
}
ll geta(int p,int l,int r){
if(l<=t[p].l&&r>=t[p].r)return t[p].a;
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
ll res=0;
if(l<=mid)res+=geta(ls(p),l,r);
if(r>mid) res+=geta(rs(p),l,r);
return res;
}
}seg;
void dfs1(int x,int fa){
depth[x]=depth[fa]+1;
sz[x]=1;
die[x]=fa;
for(vector<int>::iterator i=tree[x].begin();i!=tree[x].end();i++){
if(*i==fa)continue;
dfs1(*i,x);
sz[x]+=sz[*i];
if(sz[*i]>sz[zhongez[x]])zhongez[x]=*i;
}
}
void dfs2(int x,int top){
linktop[x]=top;
dfn[x]=++cnt;
rk[cnt]=x;
if(zhongez[x]){
dfs2(zhongez[x],top);
for(vector<int>::iterator i=tree[x].begin();i!=tree[x].end();i++){
if(*i==zhongez[x]||*i==die[x])continue;
dfs2(*i,*i);
}
}
}
void modify(int x,int y,int k){
while(linktop[x]!=linktop[y]){
if(depth[linktop[x]]<depth[linktop[y]])swap(x,y);
seg.change(1,dfn[linktop[x]],dfn[x],k);
x=die[linktop[x]];
}
if(depth[x]>depth[y])swap(x,y);
seg.change(1,dfn[x],dfn[y],k);
}
int qiuez(int x,int y){
while(linktop[x]!=linktop[y]){
if(depth[linktop[x]]<depth[linktop[y]])swap(x,y);
if(die[linktop[x]]==y)return linktop[x];
x=die[linktop[x]];
}
if(depth[x]>depth[y])swap(x,y);
return zhongez[x];
}
int __lca(int x,int y){
while(linktop[x]!=linktop[y]){
if(depth[linktop[x]]>depth[linktop[y]])
x=die[linktop[x]];
else y=die[linktop[y]];
}
return depth[x]<depth[y]?x:y;
}
int qiu_lca(int x,int y){
int lxy=__lca(x,y),lxr=__lca(x,root),lyr=__lca(y,root);
if(depth[lxy]<depth[lxr])swap(lxy,lxr);
if(depth[lxy]<depth[lyr])swap(lxy,lyr);
return lxy;
}
void solve(){
fr(n);
for(int i=1;i<n;i++){
int x,y;fr(x),fr(y);
tree[x].emplace_back(y);
tree[y].emplace_back(x);
};
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=n;i++)dsum[i]=dsum[i-1]+depth[i];
seg.build(1,1,n);
fr(m);
while(m--){
int op;fr(op);
if(op==1){
int u,v;fr(u),fr(v);
root=u;
if(root==v){
seg.change(1,dfn[1],dfn[1]+sz[1]-1,1);
}
else if(dfn[v]>dfn[root]||dfn[v]+sz[v]-1<dfn[root]){
seg.change(1,dfn[v],dfn[v]+sz[v]-1,1);
}
else{
int ez=qiuez(v,root);
if(dfn[ez]+sz[ez]-1==n)seg.change(1,1,dfn[ez]-1,1);
else{
seg.change(1,1,dfn[ez]-1,1);
seg.change(1,dfn[ez]+sz[ez],n,1);
}
}
}
else if(op==2){
int u,v;fr(u),fr(v);
modify(u,v,1);
}
else{
int v;fr(v);
ll res=seg.geta(1,1,n)*depth[v]+seg.getv(1,1,n);
while(v){
res-=2*seg.getv(1,dfn[linktop[v]],dfn[v]);
v=die[linktop[v]];
}
fw(res/2),pc('\n');
}
}
}
_Atomic_word main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int Count=1;//fr(Count);
while(Count--)solve();
return EXIT_SUCCESS;
}
/*十年OI一场空,不开LL见祖宗。
似是神牛成才处,实为蒟蒻黄泉路。
黄题有恨无正解,码力不若小学生。
今生无奈入OI,来世不做信竞人。 */
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 14804kb
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: 46ms
memory: 14600kb
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:
479 572 487 1225 1503 1073 1881 1790 2986 2690 3060 2582 3749 3388 4364 4464 3221 5629 4770 5857 5679 4158 7273 5317 7769 8571 6171 5905 6057 9204 11038 15312 10147 12327 9872 10994 8008 12963 8249 14650 17636 14938 15041 12223 11987 16853 11824 15543 12711 18306 12802 18232 13183 19444 14816 18670 ...
result:
wrong answer 1st numbers differ - expected: '826', found: '479'