제출 #1224909

#제출 시각아이디문제언어결과실행 시간메모리
1224909minhpkSprinkler (JOI22_sprinkler)C++20
0 / 100
3739 ms57304 KiB
#include <bits/stdc++.h> #define int long long using namespace std; int a,mod; const int maxn=250001; vector <int> z[maxn]; int h[maxn]; int sta[maxn]; int fin[maxn]; int tour; vector <int> depth[maxn]; int par[maxn]; int high[maxn]; int base[maxn]; int maxdepth=0; int cur=1; bool cmp(int a,int b){ return a<b; } int sbd(int i){ int res=base[high[i]]; int t=high[i]; int pre=lower_bound(depth[t].begin(),depth[t].end(),sta[i])-depth[t].begin()+1; if (pre+base[t]>a || pre+base[t]>a){ cout << i << " " << t << " " << depth[t].size() << "\n"; } res+=pre; return res; } void dfs(int i,int j,int k){ par[i]=j; tour++; sta[i]=tour; maxdepth=max(maxdepth,k); depth[k].push_back(sta[i]); for (auto p:z[i]){ if (p==j){ continue; } high[p]=high[i]+1; dfs(p,i,k+1); } fin[i]=tour; } int f[maxn*4]; int lazy[maxn*4]; pair<int,int> length[maxn]; pair<int,int> length1[maxn]; void push(int id){ if (lazy[id]!=1){ lazy[id*2]*=lazy[id]; lazy[id*2+1]*=lazy[id]; lazy[id*2]%=mod; lazy[id*2+1]%=mod; f[id*2]*=lazy[id]; f[id*2+1]*=lazy[id]; f[id*2]%=mod; f[id*2+1]%=mod; lazy[id]=1; } } void update(int id,int l,int r,int x,int y,int val){ if (x>r || y<l){ return; } if (l>=x && y>=r){ f[id]*=val; f[id]%=mod; lazy[id]=(lazy[id]*val)%mod; return; } int mid=(l+r)/2; push(id); update(id*2,l,mid,x,y,val); update(id*2+1,mid+1,r,x,y,val); f[id]=f[id*2]+f[id*2+1]; } int get(int id,int l,int r,int pos){ if (l==r){ return f[id]; } int mid=(l+r)/2; push(id); if (pos<=mid){ return get(id*2,l,mid,pos); }else{ return get(id*2+1,mid+1,r,pos); } } void queryup(int x, int d, int w) { deque<tuple<int, int, int>> dq; // (depth, sta, fin) int u = x; for (int step = 0; step <= d && u != 0; ++step) { int hi = high[u]; dq.emplace_back(hi, sta[u], fin[u]); u = par[u]; } for (int dep = 1; dep <= maxdepth; ++dep) { length[dep] = {0, -1}; } for (auto &[hi, l, r] : dq) { int lo = hi; int up = hi + (d - (hi - high[x])); up = min(up, maxdepth); for (int dep = lo; dep <= up; ++dep) { length[dep] = {l, r}; } } } void query1(int x,int d,int w){ int t=high[x]; for (int i=0;i<=d;i++){ if (t-i<=0){ break; } int sta1=t-i; int pos1=lower_bound(depth[sta1].begin(),depth[sta1].end(),length[t-i].first)-depth[sta1].begin()+1+base[sta1]; int pos2=upper_bound(depth[sta1].begin(),depth[sta1].end(),length[t-i].second)-depth[sta1].begin()+base[sta1]; if (pos1<=pos2){ update(1,1,a,pos1,pos2,w); } } for (int i=1;i<=d;i++){ if (t+i>maxdepth){ break; } int sta1=t+i; int pos1=lower_bound(depth[sta1].begin(),depth[sta1].end(),length[sta1].first)-depth[sta1].begin()+1+base[sta1]; int pos2=upper_bound(depth[sta1].begin(),depth[sta1].end(),length[sta1].second)-depth[sta1].begin()+base[sta1]; if (pos1<=pos2){ update(1,1,a,pos1,pos2,w); } } } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> a >> mod; for (int i=1;i<a;i++){ int x,y; cin >> x >> y; z[x].push_back(y); z[y].push_back(x); } for (int i=1;i<=a;i++){ cin >> h[i]; } dfs(1,0,1); for (int i=1;i<=maxdepth;i++){ base[i]=base[i-1]+depth[i-1].size(); sort(depth[i].begin(),depth[i].end(),cmp); } for (int i=1;i<=a;i++){ high[i]++; } for (int i=1;i<=4*a+5;i++){ lazy[i]=1; f[i]=1; } int q; cin >> q; while (q--){ int c; cin >> c; if (c==2){ int x; cin >> x; int pos=sbd(x); int pre=get(1,1,a,pos); cout << (h[x]*pre)%mod << "\n"; }else{ int x,d,w; cin >> x >> d >> w; int t=high[x]; for (int i=0;i<=d;i++){ length[max(t-i,1LL)]={0,-1}; length[t+i]={0,-1}; } queryup(x,d,w); query1(x,d,w); t=high[x]; for (int i=0;i<=d;i++){ length[max(t-i,1LL)]={0,-1}; length[t+i]={0,-1}; } } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...