結果
| 問題 |
No.2439 Fragile Apple Tree
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-08-18 22:46:25 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,705 ms / 10,000 ms |
| コード長 | 3,165 bytes |
| コンパイル時間 | 1,422 ms |
| コンパイル使用メモリ | 96,380 KB |
| 実行使用メモリ | 64,648 KB |
| 最終ジャッジ日時 | 2024-11-28 13:10:12 |
| 合計ジャッジ時間 | 22,918 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 30 |
ソースコード
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cassert>
#include<map>
#include<atcoder/lazysegtree>
using namespace std;
class HLD{
private:
void dfs_sz(int v) {
auto &es=G[v];
if(~par[v]) es.erase(find(es.begin(),es.end(),par[v]));
for(int &u:es){
par[u]=v;
dfs_sz(u);
sub[v]+=sub[u];
if(sub[u]>sub[es[0]]) swap(u,es[0]);
}
}
void dfs_hld(int v,int &pos) {
vid[v]=pos++;
inv[vid[v]]=v;
for(int u:G[v]){
assert(u!=par[v]);
nxt[u]=(u==G[v][0]?nxt[v]:u);
dfs_hld(u,pos);
}
}
public:
vector< vector<int> > G;
// vid: vertex -> idx
// inv: idx -> vertex
vector<int> vid,nxt,sub,par,inv;
HLD(int n):G(n),vid(n,-1),nxt(n),sub(n,1),par(n,-1),inv(n){}
void add_edge(int u,int v) {
G[u].emplace_back(v);
G[v].emplace_back(u);
}
void build(int r=0) {
int pos=0;
dfs_sz(r);
nxt[r]=r;
dfs_hld(r,pos);
}
int lca(int u,int v){
while(1){
if(vid[u]>vid[v]) swap(u,v);
if(nxt[u]==nxt[v]) return u;
v=par[nxt[v]];
}
}
template<typename F>
void for_each(int u,int v,const F& f) {
while(1){
if(vid[u]>vid[v]) swap(u,v);
f(max(vid[nxt[v]],vid[u]),vid[v]+1);
if(nxt[u]!=nxt[v]) v=par[nxt[v]];
else break;
}
}
template<typename F>
void for_each_edge(int u,int v,const F& f) {
while(1){
if(vid[u]>vid[v]) swap(u,v);
if(nxt[u]!=nxt[v]){
f(vid[nxt[v]],vid[v]+1);
v=par[nxt[v]];
}else{
if(u!=v) f(vid[u]+1,vid[v]+1);
break;
}
}
}
};
long op(long a,long b){return min(a,b);}
long e(){return 1L;}
long mp(long f,long x){return x+f;}
long cmp(long f,long g){return f+g;}
long id(){return 0L;}
int N,Q;
int U[3<<17],V[3<<17];
long C[3<<17];
bool deled[3<<17];
int cnt;
void del(int u,const HLD&hld)
{
if(deled[u])return;
deled[u]=true;
cnt++;
for(int v:hld.G[u])del(v,hld);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>N>>Q;
HLD hld(N);
for(int i=0;i+1<N;i++)
{
cin>>U[i]>>V[i]>>C[i];
U[i]--,V[i]--;
hld.add_edge(U[i],V[i]);
}
hld.build();
vector<long>init(N);
for(int i=0;i+1<N;i++)
{
int id=max(hld.vid[U[i]],hld.vid[V[i]]);
init[id]=C[i];
}
atcoder::lazy_segtree<long,op,e,long,mp,cmp,id>seg(init);
vector<pair<int,int> >Rs;
for(;Q--;)
{
int o;cin>>o;
if(o==1)
{
int v,x;
cin>>v>>x;
v--;
Rs.clear();
hld.for_each_edge(0,v,[&Rs](int l,int r){Rs.push_back(make_pair(l,r));});
for(pair<int,int>p:Rs)
{
seg.apply(p.first,p.second,-x);
//cout<<"["<<p.first<<", "<<p.second<<"), ";
}
//cout<<endl;
for(pair<int,int>p:Rs)
{
if(seg.prod(p.first,p.second)<=0)
{
int idx=seg.min_left(p.second,[](long val){return val>=1;});
assert(p.first<idx);
idx--;
int d=hld.inv[idx];
//cout<<"del "<<hld.inv[idx]+1<<endl;
//brake edge par[idx]<->idx
del(d,hld);
long up=init[idx]-seg.get(idx);
//cout<<"rec "<<up<<endl;
hld.for_each_edge(0,hld.par[d],[&seg,&up](int l,int r){seg.apply(l,r,up);});
break;
}
}
}
else cout<<N-cnt<<"\n";
}
}