【题解】CF#474(Div.1+Div.2) H-Santa's Gift

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

  \(\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 * 2], cal[maxn * 2], cal2[maxn * 2], son[maxn * 2][2];

int read()
{
    int x = 0, k = 1;
    char c; c = getchar();
    while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) k = -1; c = getchar(); }
    while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar();
    return x * k;
}

struct edge
{
    int cnp, to[maxn], last[maxn], head[maxn];
    edge() { cnp = 2; }
    void add(int u, int v)
    { to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++; }
}E1;

void dfs(int u)
{
    size[u] = 1; int mx = 0, hs = 0;
    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 + 1) * x * x;
    cal[p] += (r - l + 1) * x * 2;
}

void Push_down(int p, int l, int r)
{
    int mid = (l + r) >> 1;
    if(!mark[p]) return;
    Add(son[p][0], l, mid, mark[p]); Add(son[p][1], mid + 1, r, mark[p]);
    mark[p] = 0;
}

void Push_Up(int p)
{
    int l = son[p][0], r = son[p][1];
    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) >> 1;
    if(L <= mid) Update(son[p][0], l, mid, L, R, x);
    if(R > mid) Update(son[p][1], mid + 1, 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], 1, 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 = 1; i <= n; i ++) f[i] = read();
    for(int i = 2; i <= n; i ++) { int x = read(); E1.add(x, i); }
    for(int i = 1; i <= m; i ++) co[i] = read();
    dfs(1), dfs2(1, 1), cnt = m;
    for(int i = 1; i <= m; i ++) root[i] = i;
    for(int i = 1; i <= n; i ++) T_Update(f[i], i, 1);
    for(int i = 1; i <= q; i ++)
    {
        int opt = read();
        if(opt == 1)
        {
            int x = read(), k = read();
            T_Update(f[x], x, -1), T_Update(f[x] = k, x, 1);
        }
        else
        {
            int k = read();
            printf("%lf\n", (db) Cal(k) / (db) n);
        }
    }
    return 0;
}

【题解】CF#474(Div.1+Div.2) H-Santa's Gift

原文地址:https://www.cnblogs.com/twilight-sx/p/9760398.html

时间: 2024-10-10 10:34:36

【题解】CF#474(Div.1+Div.2) H-Santa's Gift的相关文章

Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造

Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造 [Problem Description] ? 给你一个\(n\),构造一个\(n\times n\)的矩阵,使其满足任意一行,或一列的异或值相同.保证\(n\)能被\(4\)整除. [Solution] ? 可以发现,从\(0\)开始,每\(4\)个连续数的异或值为\(0\),所以可以很容易使得每一行的异或值等于\(0\). ? 列

Codeforces Round #621 (Div. 1 + Div. 2)

Codeforces Round #621 (Div. 1 + Div. 2) A. Cow and Haybales 贪心,移到第一堆的代价即为与第一堆的距离. #include <bits/stdc++.h> using namespace std; void solve(){ int n,d;cin>>n>>d; int sum;cin>>sum; for(int i=1;i<n;i++){ int t;cin>>t; if(d>

div嵌套div 背景图片 不显示的问题

这几天 在做一个小Demo的时候碰到了如上的问题,一个DIV嵌套多个DIV时,父容器DIV不显示背景图片.同时结合之前碰到类似的问题,我归纳了如下几个解决方法: 1.就是常见的 子div 背景把父div的背景给盖住了,例子: 该例子就是 我有一个父div 和它里面嵌套的一个子div,两个div的宽度和高度大小是一样的,其中父div的背景图片就是上面这张图片(箭头部分是透明的),子div的背景图片是那种渐变灰色图片,其实懂英语的人应该看出来了就是,我想实现一个那种类似于iphone滑动那种灯光从

div 属性 DIV标签属性有什么如何设置属性

div 属性 DIV标签属性有什么如何设置属性(音乐放松椅) div 属性介绍,对DIV可加属性有哪些,DIV属性一览表DIVCSS5整理 DIVCSS5给大家整理DIV标签内常用属性,同时通过div各属性小实例,让大家认识各属性并掌握属性. div标签内常用属性列表 1.style 设置css样式(扩展了解style标签) 2.align 设置div盒子内的内容居中.居左.居右 3.id 引人外部对应#(井号)选择符号样式 4.class 引人外部对应.(句号)选择符号样式 5.title 设

DIV布局-DIV高度不同自动换行并对齐《转》

每个div框内容有多有少,要支持div高度自适应,还要添加的div自动追加,并且换行还要保持每行对齐. 刚开始的效果: 给出了完美解决方案: 效果: 因为要支持每个div可删除,删除后,后面的div自动补齐,所以用table不显示(除非想自虐的人可以试下) 最终就是css修改了一下就搞定了... 1 <html> 2 <head> 3 <style> 4 .test_area{ 5 width:100%; 6 background-color:#FFFFFF; 7 mi

xHTML+div布局:三个div,两边div宽度固定,中间div宽度自适应

xHTML+div经常考题:三个div,两边div宽度固定,中间div宽度自适应. 和大家分享一个实现方式: 1.html代码 1 <div class="dyleft">左栏固定宽度为200px</div> 2 <div class="dyright">右栏固定宽度为200px</div> 3 <div class="dycenter">中间自适应宽度</div> 2.cs

div覆盖div DIV相互重叠如何解决

div覆盖div,出现div与div盒子之间产生重叠覆盖现象,而内容没有出现覆盖重叠现象原因与解决方法.DIVCSS5通过CSS图文案例介绍产生原因与解决方法.DIV与DIV覆盖原因与解决方法. 可能您遇到过上下结构的布局,下面DIV内容重叠上面DIV内容上,也可能下面内容覆盖掉上面DIV布局,形成DIV与DIV覆盖重叠现象:您也可能遇到过相邻的两个DIV盒子发生重叠覆盖现象,这些是什么问题如何解决?(音乐休闲椅) 接下来DIVCSS5通过案例来演示这两种兼容性DIV覆盖重叠现象问题,并解释原因

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching B. Pair of Toys C. Bracket Subsequence D. Array Restoration-区间查询最值(RMQ(ST))

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching 题意就是匹配字符的题目,打比赛的时候没有看到只有一个" * ",然后就写挫了,被hack了,被hack的点就是判一下只有一个" * ". 1 //A 2 #include<iostream> 3 #include<cstdio&g

JavaScript实现页面滚动到div区域div以动画方式出现

用JavaScript实现页面滚动到div区域div以动画方式出现CSS动画 页面滚动到一块区域,改区域以动画方式出现实现这个效果需要二点:一我们要先写好一个css动画,二:用js的监听页面滑动的距离在给div添加动画 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> img { width: 1