好久没有写过数据结构题目了,果然还是太不自信。实际上就是要求统计一个式子:

  \(\sum (c[k]*p[k] - C)^{2}\)

拆开,分别统计和与平方和

\(co[k] * \sum p[k]^{2} - 2 * C * co[k] \sum p[k] + \sum C ^{2}\)

显然可以用树链剖分 + 线段树维护

平方和在区间 + 1的时候直接用 \((x + 1) ^ {2} = x^2 + 2 * x + 1\) 计算即可。

  至于不同的口味的问题,我们给每个口味都开一线段树,动态开点~听起来虽然复杂,但代码实际上超短。◕ᴗ◕。

#include <bits/stdc++.h>
using namespace std;
#define maxn 3000000
#define int long long
#define db double
int n, m, q, C, cnt, f[maxn], co[maxn], dfn[maxn];
int size[maxn], hson[maxn], top[maxn], fa[maxn];
int root[maxn], mark[maxn * ], cal[maxn * ], cal2[maxn * ], son[maxn * ][]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct edge
{
int cnp, to[maxn], last[maxn], head[maxn];
edge() { cnp = ; }
void add(int u, int v)
{ to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++; }
}E1; void dfs(int u)
{
size[u] = ; int mx = , hs = ;
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i];
fa[v] = u; dfs(v); size[u] += size[v];
if(size[v] >= mx) mx = size[v], hs = v;
}
hson[u] = hs;
} void dfs2(int u, int anc)
{
dfn[u] = ++ cnt, top[u] = anc;
if(hson[u]) dfs2(hson[u], anc);
for(int i = E1.head[u]; i; i = E1.last[i])
if(E1.to[i] != hson[u]) dfs2(E1.to[i], E1.to[i]);
} void Add(int &p, int l, int r, int x)
{
if(!p) p = ++ cnt; mark[p] += x;
cal2[p] += cal[p] * x + (r - l + ) * x * x;
cal[p] += (r - l + ) * x * ;
} void Push_down(int p, int l, int r)
{
int mid = (l + r) >> ;
if(!mark[p]) return;
Add(son[p][], l, mid, mark[p]); Add(son[p][], mid + , r, mark[p]);
mark[p] = ;
} void Push_Up(int p)
{
int l = son[p][], r = son[p][];
cal2[p] = cal2[l] + cal2[r]; cal[p] = cal[l] + cal[r];
} void Update(int &p, int l, int r, int L, int R, int x)
{
if(L > R || l > r) return;
if(!p) p = ++ cnt;
if(L <= l && R >= r) { Add(p, l, r, x); return; }
Push_down(p, l, r); int mid = (l + r) >> ;
if(L <= mid) Update(son[p][], l, mid, L, R, x);
if(R > mid) Update(son[p][], mid + , r, L, R, x);
Push_Up(p);
} void T_Update(int k, int u, int x)
{
for(; u; u = fa[top[u]])
Update(root[k], , n, dfn[top[u]], dfn[u], x);
} int Cal(int p)
{ return co[p] * co[p] * cal2[root[p]] - cal[root[p]] * C * co[p] + n * C * C; } signed main()
{
n = read(), m = read(), q = read(), C = read();
for(int i = ; i <= n; i ++) f[i] = read();
for(int i = ; i <= n; i ++) { int x = read(); E1.add(x, i); }
for(int i = ; i <= m; i ++) co[i] = read();
dfs(), dfs2(, ), cnt = m;
for(int i = ; i <= m; i ++) root[i] = i;
for(int i = ; i <= n; i ++) T_Update(f[i], i, );
for(int i = ; i <= q; i ++)
{
int opt = read();
if(opt == )
{
int x = read(), k = read();
T_Update(f[x], x, -), T_Update(f[x] = k, x, );
}
else
{
int k = read();
printf("%lf\n", (db) Cal(k) / (db) n);
}
}
return ;
}

【题解】CF#960 H-Santa's Gift的更多相关文章

  1. CF 1045 H. Self-exploration 解题报告

    CF 1045 H. Self-exploration 考虑到串的结构一定是 1...0....1....0.....1... 这样的,而\(01\)与\(10\)在转折点交替出现 首先串长一定是\( ...

  2. 【codeforces】【比赛题解】#960 CF Round #474 (Div. 1 + Div. 2, combined)

    终于打了一场CF,不知道为什么我会去打00:05的CF比赛…… 不管怎么样,这次打的很好!拿到了Div. 2选手中的第一名,成功上紫! 以后还要再接再厉! [A]Check the string 题意 ...

  3. 竞赛题解 - CF Round #524 Div.2

    CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...

  4. 竞赛题解 - [CF 1080D]Olya and magical square

    Olya and magical square - 竞赛题解 借鉴了一下神犇tly的博客QwQ(还是打一下广告) 终于弄懂了 Codeforces 传送门 『题目』(直接上翻译了) 给一个边长为 \( ...

  5. 题解 CF 1372 B

    题目 传送门 题意 给出 \(n\),输出 \(a\) ,\(b\) (\(0 < a \leq b < n\)),使\(a+b=n\)且 \(\operatorname{lcm}(a,b ...

  6. 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T5(思维)

    还是dfs? 好像自己写的有锅 过不去 看了题解修改了才过qwq #include <cstdio> #include <algorithm> #include <cst ...

  7. [题解] [CF 1250J] The Parade

    题面 题目大意: 给定一个 \(n\) , 所有军人的数量均在 \([1, n]\) 给定 \(a_i\) 代表高度为 \(i\) 的军人的个数 你要将这些军人分成 \(k\) 行, 满足下面两个条件 ...

  8. 题解 P1748 【H数】

    我来讲讲 \(dp\) 的做法 前言 昨天 \(PHY\) 大佬问我,这题怎么做?考虑到他没学过 \(set\) . \(priority_queue\) 和 \(queue\) .之后,我就想到了可 ...

  9. 题解 CF 1372A

    题目 传送门 题意 构造一个长度为n的数组,对于数组中的元素a,b,c,满足\(a+b\neq c\). 思路 直接让数组中的数全部变成1就可以了(其他数也行). 代码 /* * Author :We ...

随机推荐

  1. Spring Boot 2.x Redis多数据源配置(jedis,lettuce)

    Spring Boot 2.x Redis多数据源配置(jedis,lettuce) 96 不敢预言的预言家 0.1 2018.11.13 14:22* 字数 65 阅读 727评论 0喜欢 2 多数 ...

  2. Altium designer18设置原理图尺寸

    1. AD18版本设置原理图尺寸和以前版本不一样,具体是在界面右侧Properties里面的Sheet Sizes.

  3. 聊聊WS-Federation(test)

    本文来自网易云社区 单点登录(Single Sign On),简称为 SSO,目前已经被大家所熟知.简单的说, 就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 举例: 我们 ...

  4. 结合BeautifulSoup和hackhttp的爬虫实例

    网页页数的改变 headers头不添加

  5. <cerrno>

    文件头名称: <cerrno>(errno.h) 文件头描述: 文件内定义了如下的宏  errno 最后一个错误代码 加上其他至少的三个宏常量:EDOM,ERANGE 和EILSEQ 宏定 ...

  6. 小程序解析html和富文本编辑内容【亲测有效】

    首先去 https://github.com/icindy/wxParse 下载wxParse,只拷贝wxParse文件夹即可. 1.引入wxss @import "../../util/w ...

  7. Period :KMP

    I - Period Problem Description For each prefix of a given string S with N characters (each character ...

  8. isX字符串方法

    islower():返回True,如果字符串至少有一个字母,并且所有字母都是小写: 例如:>>> spam='Hello world' >>> spam.islow ...

  9. python3 bytes与hex_string之间的转换

    1, bytes to hex_string的转换: def byte_to_hex(bins): """ Convert a byte string to it's h ...

  10. js经典试题之数组与函数

    js经典试题之数组与函数 1:列举js的全局函数? 答案:JavaScript 中包含以下 7 个全局函数escape( ).eval( ).isFinite( ).isNaN( ).parseFlo ...