Bzoj 3730 震波 动态点分治
生活随笔
收集整理的這篇文章主要介紹了
Bzoj 3730 震波 动态点分治
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Bzoj 3730 震波
題解:
和在線的邊分治差不多。 就是將每層都信息都存下來(lái)。
然后對(duì)于每一層記錄上一層的重心是哪個(gè)。
?
對(duì)于求和的話, 從自己的那層出發(fā),然后暴力往上爬, 然后計(jì)算答案。
對(duì)于修改來(lái)說(shuō),也暴力的往上爬,對(duì)于每層所對(duì)應(yīng)的信息來(lái)修改
?
用樹狀數(shù)組來(lái)統(tǒng)計(jì)同一層、不同深度的前綴和。
本來(lái)想用線段樹,然后TLE了,非常卡。
然后用另一顆樹狀數(shù)組來(lái)容斥前綴和。
?
代碼:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 5e5; int head[N], to[N<<1], nt[N<<1], tot, dtot; int in[N], out[N], dfn[N], deep[N]; int Log[N]; struct ST {int dp[N][20], a[N];void init(int n) {for(int i = -(Log[0]=-1); i <= n; i++)Log[i] = Log[i - 1] + ((i & (i - 1)) == 0);for(int i = 1; i <= n; ++i) dp[i][0] = a[i];for(int j = 1; j <= Log[n]; j++)for(int i = 1; i+(1<<j)-1 <= n; i++){int x = dp[i][j-1], y = dp[i+(1<<(j-1))][j-1];if(deep[x] < deep[y]) dp[i][j] = x;else dp[i][j] = y;}}inline int lca(int l, int r) {l = in[l], r = in[r];if(l > r) swap(l, r);int k = Log[r-l + 1];if(deep[dp[l][k]] < deep[dp[r-(1<<k)+1][k]]) return deep[dp[l][k]];return dp[r-(1<<k)+1][k];} }st; inline void add(int u, int v){to[tot] = v; nt[tot] = head[u]; head[u] = tot++; } void dfs(int o, int u){in[u] = ++dtot;st.a[dtot] = u;deep[u] = deep[o] + 1;for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(o ^ v){dfs(u, v);st.a[++dtot] = u;}} } inline int dis(int u, int v){return deep[u]+deep[v]-2*deep[st.lca(u, v)]; } int w[N]; int a[N]; int atot; int Prt[N][2], Pr[N][2]; vector<int> vc[N][2]; int vis[N], tsz; int sz[N]; int rt, rtnum; int fa[N]; void Get_root(int o, int u){sz[u] = 1;int Max = 0;for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(vis[v] || v == o) continue;Get_root(u, v);Max = max(Max, sz[v]);sz[u] += sz[v];}Max = max(Max, tsz - sz[u]);if(Max < rtnum){rt = u;rtnum = Max;} } int Maxdep; void dfs(int g, int o, int u){sz[u] = 1;Maxdep = max(Maxdep, dis(g, u));for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(vis[v] || v == o) continue;dfs(g, u, v);sz[u] += sz[v];} } void Add(int g, int o, int u){a[dis(g, u)] += w[u];for(int i = head[u]; ~i ; i = nt[i]){int v = to[i];if(vis[v] || v == o) continue;Add(g, u, v);} } void Run(vector<int> & v){for(int i = 0; i <= Maxdep; ++i)v.pb(a[i]);for(int i = Maxdep; i >= 1; --i){int j = i;j += i & (-i);while(j <= Maxdep){v[j] += a[i];j += j & (-j);}} } void solve(int o, int u, int num){tsz = num;rtnum = num + 1;Get_root(0, u);fa[rt] = o;vis[rt] = 1;Maxdep = 0;dfs(rt, 0, rt);/// Find_Max_Deepfor(int i = 0; i <= Maxdep; ++i)a[i] = 0;Add(rt, 0, rt);Run(vc[rt][0]);if(o){Maxdep = 0;dfs(o, 0, rt);for(int i = 0; i <= Maxdep; ++i)a[i] = 0;Add(o, 0, rt);Run(vc[rt][1]);}int nrt = rt;for(int i = head[nrt]; ~i; i = nt[i]){int v = to[i];if(vis[v]) continue;solve(nrt, v, sz[v]);} } void Updata(vector<int> &v, int x, int val){int lim = v.size();if(x < 0) return ;if(x == 0){v[0] += val;return ;}while(x < lim){v[x] += val;x += x & (-x);} } int Query(vector<int> &v, int k){int lim = v.size();k = min(k, lim-1);if(k < 0) return 0;int ret = v[0];while(k > 0){ret += v[k];k -= k & (-k);}return ret; } void Updata(int x, int val){for(int i = x; i; i = fa[i]){Updata(vc[i][0], dis(x,i), val);if(fa[i]) Updata(vc[i][1], dis(fa[i], x), val);} } int Query(int x, int k){int ret = 0;for(int i = x; i; i = fa[i]){ret += Query(vc[i][0], k-dis(x,i));if(fa[i]) ret -= Query(vc[i][1], k-dis(fa[i], x));}return ret; }struct FastIO {static const int S = 1310720;int wpos;char wbuf[S];FastIO() : wpos(0) { }inline int xchar() {static char buf[S];static int len = 0, pos = 0;if (pos == len) pos = 0, len = fread(buf, 1, S, stdin);if (pos == len) return -1;return buf[pos++];}inline int xint() {int c = xchar(), x = 0, s = 1;while (c <= 32) c = xchar();if (c == '-') s = -1, c = xchar();for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';return x * s;}~FastIO() {if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;} } io; int main(){int n, m;scanf("%d%d", &n, &m);for(int i = 1; i <= n; ++i){w[i] = io.xint();}memset(head, -1, sizeof head);for(int i = 1, u, v; i < n; ++i){u = io.xint(), v = io.xint();add(u, v); add(v, u);}dfs(0, 1);st.init(dtot);solve(0, 1, n);int lastans = 0;int op, x, y;for(int i = 1; i <= m; ++i){op = io.xint(), x = io.xint(), y = io.xint();x ^= lastans, y ^= lastans;if(op){Updata(x, y-w[x]);w[x] = y;}else{lastans = Query(x,y);printf("%d\n", lastans);}}return 0; } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/MingSD/p/11164871.html
總結(jié)
以上是生活随笔為你收集整理的Bzoj 3730 震波 动态点分治的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。