답안 #588837

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
588837 2022-07-04T06:22:02 Z LastRonin Sprinkler (JOI22_sprinkler) C++14
0 / 100
1248 ms 121084 KB
#pragma GCC optimize("O3")

#include <bits/stdc++.h> 
#define ll long long
#define mp make_pair
#define f first
#define s second
#define pb push_back
#define pill pair<ll, ll>
#define speed ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;

const int N = 2e5 + 11;
const ll hsh[2] = {1555555699, 1222222763};
const ll P = 113;

mt19937_64 rofl(chrono::steady_clock::now().time_since_epoch().count());

ll n, L, q;
vector<ll> g[N];
ll sz[N];
ll h[N];
int lay[N];
ll dist[N][20];
ll cp[N];// centroid predok
bool del[N];

void dfs(ll v, ll p) {
	sz[v] = 1;
	for(auto u : g[v]) {
		if(p == u || del[u])continue;
		dfs(u, v);
		sz[v] += sz[u];
	}
}

void bdfs(ll v, ll p, ll k) {
	cp[v] = k;
	if(p == k)dist[v][lay[k]] = 1;
	else dist[v][lay[k]] = dist[p][lay[k]] + 1;
	for(auto u : g[v]) {
		if(u == p || del[u])continue;
		bdfs(u, v, k);
	}
}

int fnd(int v) {
	int p = 0;
	int siz = sz[v];
	while(p != v) {
		int c = v;
		for(auto u : g[c]) {
			if(u != p && !del[u] && sz[u] * 2ll > siz) {
				v = u;
				break;
			}
		}
		p = c;
	}
	return v;
}

void build(ll v, ll layer = 0) {
	dfs(v, 0);
	v = fnd(v);
	del[v] = 1;
	lay[v] = layer;
	for(auto u : g[v]) {
		if(!del[u])
			bdfs(u, v, v);	          	
	}
	for(auto u : g[v]) {
		if(!del[u]) {
			build(u, layer + 1);
		}
	}
}

int stp[N][41];
int per[N][41];
int als1[N], als2[N];

void add1(ll v, ll z) {
	als1[v]++;
	for(int j = z; j <= 40; j |= (j + 1))
		stp[v][j]++;				
}
void add2(ll v, ll z) {
	als2[v]++;
	for(int j = z; j <= 40; j |= (j + 1))
		per[v][j]++;				
}
ll get1(ll v, ll z) {
	if(z >= 40)return als1[v];	
	ll sum = 0;
	for(int j = z; j >= 0; j = (j & (j + 1)) - 1)
		sum = sum + stp[v][j];			
	return sum;
}
ll get2(ll v, ll z) {	
	if(z >= 40)return als2[v];	
	ll sum = 0;
	for(int j = z; j >= 0; j = (j & (j + 1)) - 1)
		sum = sum + per[v][j];			
	return sum;
}



void upd(ll a, ll c, ll b) {
	ll dis = 0;
	ll izn = a;
	int cnt = 0;
	add1(a, c);
	while(a) {
		if(cp[a] == 0)break;
		cnt++;
		assert(cnt <= 40);
		dis = dist[izn][lay[cp[a]]];
		if(c - dis >= 0) {
			add1(cp[a], c - dis);
			add2(a, c - dis);
		}				
		a = cp[a];
	}
}

ll getans(ll a) {
	ll dis = 0;
	ll izn = a;
	ll ans = als1[a];
	a = cp[a];
	ll pr = a;
	while(a) {
		dis = dist[izn][lay[a]];
		ans = ans + (als1[a] - get1(a, dis - 1)) - (als2[pr] - get2(pr, dis - 1));
		pr = a;
		a = cp[a];				
	}
	return ans;
}

int main() {
	speed;
	cin >> n >> L;
	for(int i = 1, a, b; i < n; i++) {
		cin >> a >> b;
		g[a].pb(b);
		g[b].pb(a);		
	}
	for(int i = 1; i <= n; i++) {
		cin >> h[i];	
	}
	build(1);
	cin >> q;
	while(q--) {
		ll t, a, b, c;
		cin >> t >> a;
		if(t == 1) {
			cin >> b >> c;
			upd(a, b, c);
		} else {
			ll z = getans(a);
			if(z > 0)cout << 0 << "\n";
			else cout << h[a] << "\n";
		}
	}
	
}
/*
8 10
1 3
3 5
4 7
6 7
4 5
7 8
2 4
5 8 6 4 6 2 9 3
11
1 2 2 0
2 1
1 6 1 0
2 4
2 6
1 5 2 0
2 8
1 7 2 0
2 6
2 7
2 4
*/
# 결과 실행 시간 메모리 Grader output
1 Incorrect 3 ms 5076 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 3 ms 5076 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 3 ms 5076 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5076 KB Output is correct
2 Incorrect 1248 ms 121084 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 3 ms 5076 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 3 ms 5076 KB Output isn't correct
2 Halted 0 ms 0 KB -