結果
問題 | No.2342 Triple Tree Query (Hard) |
ユーザー | vjudge1 |
提出日時 | 2024-10-16 13:30:27 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 863 ms / 10,000 ms |
コード長 | 4,033 bytes |
コンパイル時間 | 2,928 ms |
コンパイル使用メモリ | 161,404 KB |
実行使用メモリ | 40,576 KB |
最終ジャッジ日時 | 2024-10-16 13:30:57 |
合計ジャッジ時間 | 29,646 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 3 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 14 ms
5,248 KB |
testcase_03 | AC | 13 ms
5,248 KB |
testcase_04 | AC | 12 ms
5,248 KB |
testcase_05 | AC | 13 ms
5,248 KB |
testcase_06 | AC | 14 ms
5,248 KB |
testcase_07 | AC | 780 ms
33,536 KB |
testcase_08 | AC | 763 ms
33,280 KB |
testcase_09 | AC | 767 ms
33,536 KB |
testcase_10 | AC | 775 ms
33,408 KB |
testcase_11 | AC | 790 ms
33,408 KB |
testcase_12 | AC | 788 ms
33,408 KB |
testcase_13 | AC | 786 ms
33,408 KB |
testcase_14 | AC | 807 ms
33,408 KB |
testcase_15 | AC | 803 ms
33,408 KB |
testcase_16 | AC | 768 ms
33,408 KB |
testcase_17 | AC | 724 ms
38,400 KB |
testcase_18 | AC | 740 ms
40,576 KB |
testcase_19 | AC | 723 ms
38,144 KB |
testcase_20 | AC | 749 ms
39,552 KB |
testcase_21 | AC | 746 ms
40,448 KB |
testcase_22 | AC | 503 ms
33,408 KB |
testcase_23 | AC | 503 ms
33,408 KB |
testcase_24 | AC | 509 ms
33,280 KB |
testcase_25 | AC | 821 ms
33,408 KB |
testcase_26 | AC | 863 ms
33,664 KB |
testcase_27 | AC | 800 ms
33,536 KB |
testcase_28 | AC | 826 ms
33,536 KB |
testcase_29 | AC | 837 ms
33,664 KB |
testcase_30 | AC | 508 ms
33,408 KB |
testcase_31 | AC | 506 ms
33,408 KB |
testcase_32 | AC | 523 ms
33,536 KB |
testcase_33 | AC | 699 ms
33,408 KB |
testcase_34 | AC | 699 ms
33,408 KB |
testcase_35 | AC | 686 ms
33,408 KB |
testcase_36 | AC | 734 ms
33,408 KB |
testcase_37 | AC | 646 ms
33,408 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; const int N=100005,mod=998244353,INF=0x3f3f3f3f; int head[N],cnt,a[N],sz[N],son[N],top[N],dfn[N],tot,Fa[N],deps[N],arr[N]; struct edge{ int v,next; }e[N<<1]; void add_edge(int u,int v){ e[cnt]=edge{v,head[u]}; head[u]=cnt++; } void DFS(int u,int fa){ sz[u]=1; son[u]=-1; Fa[u]=fa; for(int i=head[u];~i;i=e[i].next){ const int v=e[i].v; if(v==fa) continue; deps[v]=deps[u]+1; DFS(v,u); sz[u]+=sz[v]; if(son[u]==-1 || sz[son[u]]<sz[v]) son[u]=v; } } void dfs(int u,int fa){ if(fa==-1 || son[fa]!=u) top[u]=u; else top[u]=top[fa]; arr[tot]=u; dfn[u]=tot++; if(son[u]!=-1) dfs(son[u],u); for(int i=head[u];~i;i=e[i].next){ const int v=e[i].v; if(v==fa || v==son[u]) continue; dfs(v,u); } } struct AAA{ int k,b; }; int calc(int x,AAA aa){return (1ll*aa.k*x%mod+aa.b)%mod;} AAA merge(AAA aa,AAA bb){return AAA{int(1ll*aa.k*bb.k%mod),int((1ll*bb.k*aa.b%mod+bb.b)%mod)};} namespace seg{ struct node{ node *left,*right; int val,mn,l,r; AAA tag[12]; }pool[N<<2],*root=nullptr; int cnt; node* New(int x,int deps,int l,int r){ pool[cnt]=node{nullptr,nullptr,x,deps,l,r,{}}; for(int i=0;i<12;++i) pool[cnt].tag[i]=AAA{1,0}; return pool+(cnt++); } node* build(int l,int r){ if(l+1==r) return New(a[arr[l]],deps[arr[l]],l,r); int mid=l+(r-l)/2; node* p=New(0,0,l,r); p->left=build(l,mid); p->right=build(mid,r); p->mn=min(p->left->mn,p->right->mn); return p; } void add_tag(node* p,int dis,AAA aa){ if(p==nullptr || (aa.k==1 && aa.b==0)) return; if(p->l+1==p->r && dis==0) p->val=calc(p->val,aa); p->tag[dis]=merge(p->tag[dis],aa); } void push_down(node* p){ if(p==nullptr) return; for(int i=0;i<12;++i){ if(p->tag[i].k==1 && p->tag[i].b==0) continue; if(i==11){ for(int j=max(0,p->mn+11-p->left->mn);j<12;++j) add_tag(p->left,j,p->tag[i]); for(int j=max(0,p->mn+11-p->right->mn);j<12;++j) add_tag(p->right,j,p->tag[i]); }else{ if(p->mn+i-p->left->mn>=0) add_tag(p->left,p->mn+i-p->left->mn,p->tag[i]); if(p->mn+i-p->right->mn>=0) add_tag(p->right,p->mn+i-p->right->mn,p->tag[i]); } p->tag[i]=AAA{1,0}; } } int query(node* p,int l,int r,int pos){ if(l+1==r) return p->val; push_down(p); int mid=l+(r-l)/2; if(pos<mid) return query(p->left,l,mid,pos); return query(p->right,mid,r,pos); } void update(node* p,int L,int R,int l,int r,int deps,AAA aa){ if(l>=r) return; if(l<=L && R<=r){ if(deps==INF){ for(int i=0;i<12;++i) add_tag(p,i,aa); }else if(deps>=p->mn) add_tag(p,deps-p->mn,aa); return; } push_down(p); int mid=L+(R-L)/2; if(l<mid) update(p->left,L,mid,l,r,deps,aa); if(r>mid) update(p->right,mid,R,l,r,deps,aa); } } int main(){ ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); memset(head,255,sizeof(head)); int n,q; cin >> n >> q; for(int i=0,u,v;i<n-1;++i){ cin >> u >> v; --u; --v; add_edge(u,v); add_edge(v,u); } for(int i=0;i<n;++i) cin >> a[i]; deps[0]=0; DFS(0,-1); dfs(0,-1); seg::root=seg::build(0,n); while(q--){ int op,u,v,k,b,r; cin >> op; if(op==1){ cin >> u; --u; cout << seg::query(seg::root,0,n,dfn[u]) << '\n'; }else if(op==4){ cin >> u >> v >> k >> b; --u; --v; while(top[u]!=top[v]){ if(deps[top[u]]<deps[top[v]]) swap(u,v); seg::update(seg::root,0,n,dfn[top[u]],dfn[u]+1,INF,AAA{k,b}); u=Fa[top[u]]; } if(dfn[u]>dfn[v]) swap(u,v); seg::update(seg::root,0,n,dfn[u],dfn[v]+1,INF,AAA{k,b}); }else if(op==3){ cin >> u >> k >> b; --u; seg::update(seg::root,0,n,dfn[u],dfn[u]+sz[u],INF,AAA{k,b}); }else{ cin >> u >> r >> k >> b; --u; for(int num=0;num<=r;++num){ if(num<r && u==0){ for(int i=r-num;i>=0;--i) seg::update(seg::root,0,n,dfn[u],dfn[u]+sz[u],deps[u]+i,AAA{k,b}); break; }else{ seg::update(seg::root,0,n,dfn[u],dfn[u]+sz[u],deps[u]+r-num,AAA{k,b}); if(num<r) seg::update(seg::root,0,n,dfn[u],dfn[u]+sz[u],deps[u]+r-num-1,AAA{k,b}); } u=Fa[u]; } } } return 0; }