zoukankan      html  css  js  c++  java
  • [HNOI2015]开店

    如果没有年龄区间
    画图发现ans=(sum_{i=1}^n dis_i + n * dis_u - 2 * sum_{i=1}^{n} dis_{lca(i, u)})

    (sum_{i=1}^{n} dis_{lca(i, u)})用树链剖分,对于每个点,都向上走到根,记录每条路经过次数,询问时从u向上跳,每次加边权*覆盖次数即可

    现在有年龄区间,加个前缀和,计算点权在[L,R]内的点到点u的距离,用主席树

    然而主席树怎么pushdown,加上标记永久化

    # include <bits/stdc++.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(3e6 + 10), __(1e7 + 10);
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, m, Q, A, id[_], o[_];
    int fst[_], nxt[_], to[_], w[_], size[_], fa[_], dfn[_], top[_], cnt, son[_], pos[_];
    int rt[__], ls[__], rs[__], cov[__];
    ll dis[_], sdis[_], sum[__];
    
    IL bool Cmp(RG int x, RG int y){  return o[x] < o[y];  }
    
    IL void Add(RG int u, RG int v, RG int f){  w[cnt] = f; to[cnt] = v; nxt[cnt] = fst[u]; fst[u] = cnt++;  }
    
    IL void Dfs1(RG int u){
    	size[u] = 1;
    	for(RG int e = fst[u]; e != -1; e = nxt[e]){
    		if(size[to[e]]) continue;
    		dis[to[e]] = dis[u] + w[e]; fa[to[e]] = u;
    		Dfs1(to[e]);
    		size[u] += size[to[e]];
    		if(size[to[e]] > size[son[u]]) son[u] = to[e];
    	}
    }
    
    IL void Dfs2(RG int u, RG int Top){
    	dfn[u] = ++cnt; top[u] = Top; pos[cnt] = u;
    	if(son[u]) Dfs2(son[u], Top);
    	for(RG int e = fst[u]; e != -1; e = nxt[e])
    		if(!dfn[to[e]]) Dfs2(to[e], to[e]);
    }
    
    IL void Build(RG int &x, RG int l, RG int r){
    	x = ++cnt;
    	if(l == r) return;
    	RG int mid = (l + r) >> 1;
    	Build(ls[x], l, mid); Build(rs[x], mid + 1, r);
    }
    
    IL void Modify(RG int &x, RG int l, RG int r, RG int L, RG int R){
    	sum[++cnt] = sum[x]; ls[cnt] = ls[x]; rs[cnt] = rs[x]; cov[cnt] = cov[x]; x = cnt;
    	sum[x] += dis[pos[R]] - dis[fa[pos[L]]];
    	if(L <= l && R >= r){  cov[x]++; return;  }
    	RG int mid = (l + r) >> 1;
    	if(R <= mid) Modify(ls[x], l, mid, L, R);
    	else if(L > mid) Modify(rs[x], mid + 1, r, L, R);
    	else Modify(ls[x], l, mid, L, mid), Modify(rs[x], mid + 1, r, mid + 1, R);
    }
    
    IL ll Query(RG int x, RG int ad, RG int l, RG int r, RG int L, RG int R){
    	if(L <= l && R >= r) return sum[x] + 1LL * ad * (dis[pos[R]] - dis[fa[pos[L]]]);
    	RG int mid = (l + r) >> 1;
    	if(R <= mid) return Query(ls[x], ad + cov[x], l, mid, L, R);
    	if(L > mid) return Query(rs[x], ad + cov[x], mid + 1, r, L, R);
    	return Query(ls[x], ad + cov[x], l, mid, L, mid) + Query(rs[x], ad + cov[x], mid + 1, r, mid + 1, R);
    }
    
    IL ll Calc(RG int u, RG int i){
    	RG ll ans = 0;
    	while(top[u] ^ 1) ans += Query(rt[i], 0, 1, n, dfn[top[u]], dfn[u]), u = fa[top[u]];
    	ans += Query(rt[i], 0, 1, n, 1, dfn[u]);
    	return ans;
    }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); Q = Read(); A = Read();
    	for(RG int i = 1; i <= n; ++i) o[i] = Read(), id[i] = i, fst[i] = -1;
    	sort(id + 1, id + n + 1, Cmp); sort(o + 1, o + n + 1);
    	for(RG int i = 1, aa, b, c; i < n; ++i) aa = Read(), b = Read(), c = Read(), Add(aa, b, c), Add(b, aa, c);
    	Dfs1(1); cnt = 0; Dfs2(1, 1); cnt = 0; Build(rt[0], 1, n);
    	for(RG int i = 1; i <= n; ++i){
    		RG int u = id[i]; rt[i] = rt[i - 1];
    		sdis[i] = sdis[i - 1] + dis[u];
    		while(top[u] ^ 1) Modify(rt[i], 1, n, dfn[top[u]], dfn[u]), u = fa[top[u]];
    		Modify(rt[i], 1, n, 1, dfn[u]);
    	}
    	for(RG ll L, R, u, a, b, ans = 0; Q; --Q){
    		u = Read(); a = Read(); b = Read();
    		L = min((a + ans) % A, (b + ans) % A);
    		R = max((a + ans) % A, (b + ans) % A);
    		L = lower_bound(o + 1, o + n + 1, L) - o;
    		R = lower_bound(o + 1, o + n + 1, R + 1) - o - 1;
    		ans = 1LL * (R - L + 1) * dis[u] + sdis[R] - sdis[L - 1] - 2LL * (Calc(u, R) - Calc(u, L - 1));
    		printf("%lld
    ", ans);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    设计模式系列
    Python3 系列之 可变参数和关键字参数
    设计模式系列
    【HANA系列】SAP HANA ODBC error due to mismatch of version
    【FICO系列】SAP FICO FS00修改科目为未清项目管理
    【FIORI系列】SAP OpenUI5 (SAPUI5) js框架简单介绍
    【HANA系列】SAP HANA SQL获取当前日期加若干天后的日期
    【HANA系列】SAP HANA SQL获取本周的周一
    【HANA系列】SAP HANA SQL获取当前日期
    【HANA系列】SAP HANA SQL获取当前日期最后一天
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8213300.html
Copyright © 2011-2022 走看看