ACM-ICPC 2018 沈阳赛区网络预赛
Posted littlepear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM-ICPC 2018 沈阳赛区网络预赛相关的知识,希望对你有一定的参考价值。
昨天学弟写的,感觉题目挺好的,今天写了写。
和以前分块一样,但这题很难想到用分块做。
像是一次操作大量的区间单点修改,区间查询……
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; int cnt[205][maxn]; ll val[maxn]; vector<int> g[maxn]; int ord[maxn]; int L[maxn], R[maxn], depth[maxn]; int ind = 0; void dfs(int u, int fa, int dep) { L[u] = ++ind; ord[ind] = u; depth[ind] = dep; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(v == fa) continue; dfs(v, u, dep + 1); } R[u] = ind; } int posl[205], posr[205]; int pos[maxn]; ll sum[205]; int t = 0; void change(int dep,int x) { val[dep] += (ll)x; for(int i = 1; i <= t; i++) { sum[i] += (ll)x * cnt[i][dep]; } } ll query(int l, int r) { int p = pos[l], q = pos[r]; ll ans = 0; if(p == q) { for(int i = l; i <= r; i++) { ans += val[depth[i]]; } } else { for(int i = p + 1; i <= q - 1; i++) { ans += sum[i]; } for(int i = l; i <= posr[p]; i++) { ans += val[depth[i]]; } for(int i = posl[q]; i <= r; i++) { ans += val[depth[i]]; } } return ans; } int main() { int n, q; scanf("%d %d", &n, &q); for(int i = 1; i <= n - 1; i++) { int u, v; scanf("%d %d", &u, &v); g[u].push_back(v); g[v].push_back(u); } dfs(1, -1, 0); t = min(200, (int)sqrt(n)); int len = n / t; for(int i = 1; i <= t; i++) { posl[i] = (i - 1) * len + 1; posr[i] = i * len; } if(posr[t] < n) t++, L[t] = R[t - 1] + 1, R[t] = n; ///预处理 for(int i = 1; i <= t; i++) { for(int j = posl[i]; j <= posr[i]; j++) { pos[j] = i; cnt[i][depth[j]]++; } } while(q--) { int op, l, x; scanf("%d", &op); if(op == 1) { scanf("%d %d", &l, &x); change(l, x); } else { scanf("%d", &x); printf("%lld ", query(L[x], R[x])); } } return 0; }
以上是关于ACM-ICPC 2018 沈阳赛区网络预赛的主要内容,如果未能解决你的问题,请参考以下文章
ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph
ACM-ICPC 2018 沈阳赛区网络预赛 KSupreme Number