結果
| 問題 |
No.1216 灯籠流し/Lanterns
|
| コンテスト | |
| ユーザー |
snow39
|
| 提出日時 | 2020-09-06 14:33:33 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,607 bytes |
| コンパイル時間 | 1,802 ms |
| コンパイル使用メモリ | 120,128 KB |
| 実行使用メモリ | 35,712 KB |
| 最終ジャッジ日時 | 2024-11-29 07:08:41 |
| 合計ジャッジ時間 | 15,654 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 11 WA * 37 |
ソースコード
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define all(v) v.begin(),v.end()
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
template<class T> void chmin(T &a,const T &b){if(a>b) a=b;}
template<class T> void chmax(T &a,const T &b){if(a<b) a=b;}
class BIT{//1-indexed
public:
vector<ll> bit;
BIT(){}
BIT(int size){
bit.resize(size,0);
}
void initialize(int size){
bit.resize(size,0);
}
ll sum(int i){
ll s=0;
while(i>0){
s+=bit[i];
i-=i&(-i);
}
return s;
}
void add(int i,ll x){//i!=0
while(i<bit.size()){
bit[i]+=x;
i+=i&(-i);
}
}
};
struct Edge{
int to,id;
ll dist;
Edge(int to,ll dist=1,int id=0):to(to),dist(dist),id(id){}
};
// this class's update method is empty.
struct HeavyLightDecomposition{
vector<vector<Edge>> g;
vector<int> in,out,head,par,dep,sz;
int times;
int root;
vector<int> rev;
vector<ll> dist;
vector<ll> disrev;
HeavyLightDecomposition(int V,vector<vector<Edge>> &G,int root=0):
g(G),in(V),out(V),head(V),par(V),dep(V),sz(V),root(root),dist(V),rev(V),disrev(V){
times=0;
sz_dfs(root,-1);
hld_dfs(root,-1);
for(int i=0;i<V;i++) disrev[i]=dist[rev[i]];
}
void sz_dfs(int now,int p){
par[now]=p;
sz[now]=1;
if(p==-1){
dep[now]=0;
dist[now]=0;
}else dep[now]=dep[p]+1;
for(auto &e:g[now]){
if(e.to==p) continue;
dist[e.to]=dist[now]+e.dist;
sz_dfs(e.to,now);
sz[now]+=sz[e.to];
if(sz[e.to]>sz[g[now][0].to]) swap(e,g[now][0]);
}
}
void hld_dfs(int now,int p){
in[now]=times++;
rev[in[now]]=now;
for(auto e:g[now]){
if(e.to==p) continue;
head[e.to]=(e.to == g[now][0].to ? head[now] : e.to);
hld_dfs(e.to,now);
}
out[now]=times;
}
int lca(int u,int v){
for(;;v=par[head[v]]){
if(in[u]>in[v]) swap(u,v);
if(head[u]==head[v]) return u;
}
}
int distance(int u,int v){
return dep[u]+dep[v]-2*dep[lca(u,v)];
}
int climb(int v,ll lim){
for(;;v=par[head[v]]){
int u=head[v];
if(u==0||dist[par[u]]+lim<dist[v]){
int z=lower_bound(disrev.begin()+in[u],disrev.end(),dist[v]-lim)-disrev.begin();
return rev[z];
}
lim-=(dist[v]-dist[par[u]]);
}
}
/*ex)
hld.update(u,x,[&](int a,int b,ll x){
seg.add(a,b,x);
});
*/
template<class T,class G>
void update(int v,const T &x,const G &g){//辺の時は0を使わない(INFのまま)
//g(in[v]+1,out[v],x);//部分木(辺)
//g(in[v],out[v],x);//部分木(頂点)
//g(in[v],in[v]+1,x);//一点
}
/*ex)
ll ans=0;
hld.query(u,v,[&](int a,int b){
ans+=seg.getSum(a,b);
},true);
*/
template<class F>
void query(int u,int v,ll x,const F &f,bool isedge){
for(;;v=par[head[v]]){
if(in[u]>in[v]) swap(u,v);
if(head[u]==head[v]) break;
f(in[head[v]],in[v]+1,x);
}
if(isedge&&u==v) return;
f(in[u]+isedge,in[v]+1,x);
}
};
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
int N,Q;
cin>>N>>Q;
vector<vector<Edge>> g(N);
rep(i,N-1){
int a,b;
ll c;
cin>>a>>b>>c;
a--;b--;
g[a].push_back({b,c});
g[b].push_back({a,c});
}
vector<int> type(Q),V(Q);
vector<ll> T(Q),L(Q);
rep(i,Q) cin>>type[i]>>V[i]>>T[i]>>L[i];
rep(i,Q) V[i]--;
HeavyLightDecomposition hld(N,g);
int sz=1;
while(sz<N) sz*=2;
vector<vector<ll>> segment(2*sz);
auto preadd = [&](int l,int r,ll x){
l+=sz;r+=sz;
while(l<r){
if(l&1) segment[l++].push_back(x);
if(r&1) segment[--r].push_back(x);
l>>=1;r>>=1;
}
};
vector<int> up(Q,-1);
for(int q=0;q<Q;q++){
if(type[q]==1) continue;
up[q]=hld.climb(V[q],L[q]);
hld.query(V[q],up[q],T[q]+hld.dist[V[q]],[&](int l,int r,ll x){
preadd(l,r,x);
},false);
}
vector<BIT> bit(2*sz);
for(int i=0;i<2*sz;i++){
sort(all(segment[i]));
segment[i].erase(unique(all(segment[i])),segment[i].end());
bit[i].initialize(segment[i].size()+1);
}
auto add = [&](int l,int r,ll x){
l+=sz;r+=sz;
while(l<r){
if(l&1){
int z=lower_bound(all(segment[l]),x)-segment[l].begin();
bit[l].add(z+1,1);
l++;
}
if(r&1){
--r;
int z=lower_bound(all(segment[r]),x)-segment[r].begin();
bit[r].add(z+1,1);
}
l>>=1;r>>=1;
}
};
for(int q=0;q<Q;q++){
if(type[q]==0){
hld.query(V[q],up[q],T[q]+hld.dist[V[q]],[&](int l,int r,ll x){
add(l,r,x);
},false);
}else{
ll target=T[q]+hld.dist[V[q]];
int ans=0;
int now=V[q]+sz;
while(now>=1){
int z=upper_bound(all(segment[now]),target)-segment[now].begin();
ans+=bit[now].sum(z);
now>>=1;
}
cout<<ans<<endl;
}
}
return 0;
}
snow39