首页 > 其他分享 >CF396C On Changing Tree 题解

CF396C On Changing Tree 题解

时间:2023-12-27 23:22:50浏览次数:25  
标签:int 题解 cin 300010 dep CF396C Changing define

CF396C

考虑将贡献表示出来:\(\forall v\in \text{subtree}_u\),\(v\) 会加上 \(x - (dep_v - dep_u)k\),然后发现这个东西可以维护整棵子树,即把 \(x,dep_u\times k\) 和 \(dep_v\times k\) 分开计算,然后 \(dep_v\) 可以最后再管,就变为子树加,单点和了。用树状数组维护 dfs 序即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define TIME 1e3 * clock() / CLOCKS_PER_SEC
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define ll long long
#define eb emplace_back
const int mod = 1e9 + 7;
int n, m;
int dn, dfn[300010], sz[300010], dep[300010];
vector<int> e[300010];
struct BIT {
	int v[300010];
	void add(int x, int y) {
		for(; x <= n; x += x & -x) v[x] = (v[x] + y) % mod;
	}
	int ask(int x) {
		int res = 0;
		for(; x; x -= x & -x) res = (res + v[x]) % mod;
		return res;
	}
	void upd(int l, int r, int v) { add(l, v), add(r + 1, -v); };
} t1, t2;
void dfs(int x) {
	dfn[x] = ++dn, sz[x] = 1;
	for(int y : e[x]) dep[y] = dep[x] + 1, dfs(y), sz[x] += sz[y];
}
int main(){
	ios :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n;
	L(i, 2, n) {
		int x; cin >> x;
		e[x].eb(i);
	}
	dfs(1);
	cin >> m;
	L(_, 1, m) {
		int opt, v; cin >> opt >> v;
		if(opt == 1) {
			int x, k; cin >> x >> k;
			int l = dfn[v], r = dfn[v] + sz[v] - 1;
			t1.upd(l, r, k), t2.upd(l, r, (dep[v] * 1ll * k + x) % mod);
		} else {
			cout << (t2.ask(dfn[v]) - t1.ask(dfn[v]) * 1ll * dep[v] % mod + 2 * mod) % mod << "\n";
		}
	}
	cerr << TIME << "ms\n";
	return 0;
}

接下来的部分没有代码。

这个方法可以扩展到全局操作。

对深度操作在根的时候是很方便的,考虑转化到根,这里可以采用对边赋值然后求树上前缀和的方法,但这里不需要对其兄弟产生贡献,所以没有必要转换到根。

具体地,令 \(u\) 为当前节点,给 \(u\) 子树内的边都减去 \(k\),然后给 \((u,fa_u)\) 这条边的权值加上 \(x\) 即可。所以这里需要树链剖分,且需支持区间加,区间和。

标签:int,题解,cin,300010,dep,CF396C,Changing,define
From: https://www.cnblogs.com/Pengzt/p/17931672.html

相关文章

  • TinyMCE富文本编辑器粘贴图片自动上传问题解决
    TinyMCE编辑器支持粘贴图片,但是自动会将图片转换成base64编码,这样将内容提交到后台,数据会很大。  图|TinyMCE本文内容配置TinyMCE(版本:5.10.0)向编辑器中粘贴图片自动上传到后台,以下为配置代码:tinymce.init({selector:'#textarea',plugins:'previewautolink......
  • Ping不通问题解决 windows 查看对端MAC地址 ARP -a
    Ping不通问题解决   Linux查看ARP信息指南(linux查看arp) ARP(地址解析协议)是TCP/IP协议提供的网络层协议,通过ARP可以查看网络层面上当前可连接的本地网络内每个主机的MAC地址。 ##查看系统的ARP信息 Linux系统中查看ARP信息的方法有很多,下面简单介绍几种常见的查......
  • 题解 P9993【[Ynoi Easy Round 2024] TEST_133】
    就硬把线段树3和数列分块入门2揉到一起出。维护原数组\(a\)及其历史最大值\(hist\),对每个块,维护块内\(a\)升序排序后结果\(p\)、块内\(a\)升序排序后历史最大值前缀和\(prehist\)、块加标记\(add\)、块历史和加标记\(histadd\)。下传标记和区间修改操作仿照线......
  • [WC2018] 通道题解
    先考虑只有两颗树要咋做,柿子先变成\(dep_x+dep_y-2\timesdep_{lca}+dist_2(x,y)\)我们可以新建节点\(x'\rightarrowx\),边权为\(dep_x\),这样上面的式子可以看作枚举\(lca\)后,选出一个端点在不同子树中的直径,可以直接\(DP\)合并直径再考虑多了一颗树,我们可以进行边分治,枚......
  • ARC167D Good Permutation 题解
    ARC167D看到排列并且有\(i\getsa_i\),就可以直接建出图来,显然是若干个不相干的环。如果不求字典序最小,就可以直接不在同一个环中的\(i,j\)直接交换就可以了,因为它要求了最小化操作数。如果求字典序最小,直接从前往后扫一遍,可以用set维护不在这个环中且\(j>i\)的最小值,如果......
  • ARC105E Keep Graph Disconnected 题解
    ARC105E正向考虑是很难的,从结果入手,发现最后一定是分别包含\(1\),\(n\)的两个完全图。考虑表示出这两个人一共加了多少边:\(\frac{n(n-1)}{2}-m-x(n-x)\),\(x\)表示点\(1\)所在集合的大小。由于是判断先手还是后手必胜,所以只需看结果对\(2\)的余数,于是对\(n\)的奇偶进行......
  • P5513 [CEOI2013] Board 题解
    P5513容易发现,每次等价于对一个二进制数进行操作。但是这个二进制数长为\(n\),即需要高精。但是这样支持加一和减一是复杂度会退化为\(\mathcal{O}(n^2)\),有一个很正常的做法就压位,仿照bitset的做法进行操作,复杂度\(\mathcal{O}(\frac{n^2}{w})\)。这样已经可以通过了,但发......
  • 模拟赛简要题解
    11.16(C0389)100+10+50=160,rk3。本来BC都应该写出来的。A:dp或贪心都可以,贪心直接从下往上覆盖即可。B:注意:这里的\(\oplus\)指的是按位或。合法条件可以化简为:\(\oplus_{i=1}^{p}a_i=\oplus_{i=p+1}^{n}a_i\)。继续挖掘。看到位运算肯定想到拆位,考虑每一位第一次和......
  • 【数据结构】P4338 [ZJOI2018] 历史 题解
    P4338先考虑怎么安排崛起的先后顺序最优。但是发现好像没有一个很好的顺序去进行崛起,并且由于\(a_i\)的值域会很大,所以即使知道顺序应该也会难以进行维护。转换一下方向,正难则反。考虑每个点的贡献,但是颜色不同时只会算一次,所以要钦定是哪一个点造成的贡献。令当前考虑的点为......
  • CF1896D Ones and Twos 题解
    CF1896D如果只有单次询问其实可以双指针,但是这个难以进行拓展。考虑找点性质。发现\(a_i,v\in\{1,2\}\),从值域上下手。发现若存在和为\(S\)的方案,则一定有和为\(S-2\)的方案,因为可以直接\(-2\)或\(-1-1\)。然后就变为找最大的和为奇/偶数了,因为如果最大的都不行就肯定......