zoukankan      html  css  js  c++  java
  • Jamie and Tree CodeForces

    大意: n节点树, 每个点有权值, 三种操作: 1,换根. 2, lca(u,v)的子树权值全部增加x. 3, 查询子树权值和.

    先不考虑换根, 考虑子树x加v的贡献

    (1)对fa[x]到根的树链贡献为sz[x]*v;

    (2)对x子树内的点y贡献为sz[y]*v;

    步骤(1)可以用单点更新子树求和实现, 步骤(2)可以子树更新单点求和实现

    然后就是换根板子题了.

    感觉蠢得不行的题啊, 还是打了好久, 怎么能这么菜啊

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <bitset>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    #define DB(a) {REP(i,1,n) cout<<a[i]<<' ';hr;}
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
    ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
    //head
    
    
    
    
    #ifdef ONLINE_JUDGE
    const int N = 1e6+10;
    #else
    const int N = 111;
    #endif
    
    
    int n, a[N];
    vector<int> g[N];
    int sz[N], dep[N], fa[N], L[N], R[N];
    int son[N], top[N];
    ll c[N], c2[N];
    void add(int x, ll v) {
    	for (; x<=n; x+=x&-x) c[x]+=v;
    }
    void add2(int x, int v) {
    	for (; x; x^=x&-x) c2[x]+=v;
    }
    void add2(int l, int r, int v) {
    	add2(r,v),add2(l-1,-v);
    }
    ll qry(int x) {
    	ll ret = 0;
    	for (; x; x^=x&-x) ret += c[x];
    	return ret;
    }
    ll qry(int l, int r) {
    	return qry(r)-qry(l-1);
    }
    ll qry2(int x) {
    	ll ret = 0;
    	for (; x<=n; x+=x&-x) ret += c2[x];
    	return ret;
    }
    void dfs(int x, int d, int f) {
    	sz[x] = 1, dep[x]=d, fa[x]=f, L[x]=++*L, add(L[x],a[x]);
    	for (int y:g[x]) if (y!=f) {
    		dfs(y,d+1,x); sz[x]+=sz[y];
    		if (sz[y]>sz[son[x]]) son[x]=y;
    	}
    	R[x]=*L;
    }
    void dfs2(int x, int tf) {
    	top[x]=tf;
    	if (son[x]) dfs2(son[x],tf);
    	for (int y:g[x]) if (y!=fa[x]&&y!=son[x]) dfs2(y,y);
    }
    int lca(int x, int y) {
    	while (top[x]!=top[y]) {
    		if (dep[top[x]]<dep[top[y]]) swap(x,y);
    		x = fa[top[x]];
    	}
    	if (dep[x]>dep[y]) swap(x,y);
    	return x;
    }
    int lca(int u, int v, int rt) {
    	int L = lca(u,v);
    	if (lca(rt,L)!=L) return L;
    	int x=lca(u,rt),y=lca(v,rt);
    	if (dep[x]<dep[y]) swap(x,y);
    	return x;
    }
    int calc(int x, int y) {
    	int f = x, pre = 0, lca;
    	while (top[x]!=top[y]) {
    		if (dep[top[x]]<dep[top[y]]) swap(x,y);
    		pre = top[x], x = fa[pre];
    	}
    	if (x==y) lca=x;
    	else lca=dep[x]<dep[y]?x:y;
    	if (lca!=f) return 0;
    	return fa[pre]==f?pre:son[f];
    }
    void update(int x, int v) {
    	add(L[fa[x]],(ll)sz[x]*v);
    	add2(L[x],R[x],v);
    }
    void update(int x, int v, int rt) {
    	if (x==rt) return add2(1,n,v);
    	int t = calc(x,rt);
    	if (!t) return update(x,v);
    	add2(1,n,v),update(t,-v);
    }
    ll query(int x) {
    	return qry(L[x],R[x])+sz[x]*qry2(L[x]);
    }
    ll query(int x, int rt) {
    	if (x==rt) return query(1);
    	int t = calc(x,rt);
    	if (!t) return query(x);
    	return query(1)-query(t);
    }
    
    int main() {
    	int q, rt = 1;
    	scanf("%d%d", &n, &q);
    	REP(i,1,n) scanf("%d", a+i);
    	REP(i,2,n) {
    		int u, v;
    		scanf("%d%d", &u, &v);
    		g[u].pb(v),g[v].pb(u);
    	}
    	dfs(1,0,0),dfs2(1,1);
    	while (q--) {
    		int op, u, v, w;
    		scanf("%d%d", &op, &u);
    		if (op==1) rt=u;
    		else if (op==2) {
    			scanf("%d%d", &v, &w);
    			update(lca(u,v,rt),w,rt);
    		}
    		else printf("%lld
    ", query(u,rt));
    	}
    }
    
  • 相关阅读:
    Treap 树堆 容易实现的平衡树
    (转)Maven实战(二)构建简单Maven项目
    (转)Maven实战(一)安装与配置
    根据请求头跳转判断Android&iOS
    (转)苹果消息推送服务器 php 证书生成
    (转)How to renew your Apple Push Notification Push SSL Certificate
    (转)How to build an Apple Push Notification provider server (tutorial)
    (转)pem, cer, p12 and the pains of iOS Push Notifications encryption
    (转)Apple Push Notification Services in iOS 6 Tutorial: Part 2/2
    (转)Apple Push Notification Services in iOS 6 Tutorial: Part 1/2
  • 原文地址:https://www.cnblogs.com/uid001/p/10632383.html
Copyright © 2011-2022 走看看