题目简述

一个\(N\)个节点的树,有\(M\)个炸弹分布在一些节点上,有各自的威力,随着其他点距离增大对其他点的伤害呈等差减小,直至为0

问每个点受到的伤害

题解

QAQ考场代码没处理好有些炸弹威力很大这个事实,,数组爆掉。。。

AC算法直接变暴力分,,,

点分治即可

我是每次将子树内所有的炸弹统计到根来,再用一个差分数组求出各个深度受到的伤害,累加入每个节点的答案

但是由于可能会出现伤害来自同一个子树的情况,我们再对每个子树做一遍撤销

常数略大,,经玄学优化强行卡入时限

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
using namespace std;
const int maxn = 500005,maxm = 600005,INF = 100000000;
inline int read(){
int out = 0; char c = getchar();
while (c < 48 || c > 57) c = getchar();
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out;
}
inline void write(LL x){
LL tmp = 0; int cnt = 0;
while (x) tmp = (tmp << 3) + (tmp << 1) + x % 10,x /= 10,cnt++;
while (cnt--) putchar(tmp % 10 + 48),tmp /= 10;
putchar('\n');
}
int h[maxn],ne = 2,n,m;
struct EDGE{int to,nxt;}ed[maxn * 2];
int F[maxn],Siz[maxn],rt,sum,vis[maxn];
int siz[maxn],st[maxm],top,d[maxn],fa[maxn],nd[maxn],ndi;
int md;
LL ans[maxn],D[maxn];
vector<int> power[maxn];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
void getRT(int u){
Siz[u] = 1 + power[u].size();
F[u] = 0;
Redge(u) if (!vis[to = ed[k].to] && to != fa[u]){
fa[to] = u;
getRT(to);
Siz[u] += Siz[to];
F[u] = max(F[u],Siz[to]);
}
F[u] = max(F[u],sum - Siz[u]);
if (F[u] < F[rt]) rt = u;
}
void dfs1(int u){
Siz[u] = 1 + power[u].size(); siz[u] = 1;
nd[++ndi] = u;
md = max(md,d[u]);
Redge(u) if (!vis[to = ed[k].to] && to != fa[u]){
fa[to] = u; d[to] = d[u] + 1;
dfs1(to);
Siz[u] += Siz[to];
siz[u] += siz[to];
}
}
void dfs4(int u){
nd[++ndi] = u;
for (int j = 0; j < power[u].size(); j++){
if (power[u][j] > d[u] + 1) st[++top] = power[u][j] - d[u] - 1;
}
Redge(u) if (!vis[to = ed[k].to] && to != fa[u]){
dfs4(to);
}
}
void dfs5(int u){
ans[u] -= D[d[u]];
Redge(u) if (!vis[to = ed[k].to] && to != fa[u]){
dfs5(to);
}
}
void cal(int u){
top = 0;
for (int j = 0; j < power[u].size(); j++)
if (power[u][j] > 2) st[++top] = power[u][j] - 2;
for (int i = 0; i <= siz[u]; i++) D[i] = 0;
ndi = 0;
Redge(u) if (!vis[to = ed[k].to] && to != fa[u]){
dfs4(to);
}
for (int i = 1; i <= top; i++){
if (st[i] <= md){
D[1] += st[i];
D[2] += -1 - st[i];
D[st[i] + 2] += 1;
}
else {
D[1] += st[i];
D[2] += -1 - st[i];
}
}
for (int i = 1; i <= siz[u]; i++) D[i] += D[i - 1];
for (int i = 1; i <= siz[u]; i++) D[i] += D[i - 1];
ans[u] -= D[1];
for (int i = 1; i <= ndi; i++) ans[nd[i]] -= D[d[nd[i]]];
}
void solve(int u){
vis[u] = true; siz[u] = 1; Siz[u] = 1 + power[u].size();
ndi = 0; md = 0;
Redge(u) if (!vis[to = ed[k].to]){
fa[to] = u; d[to] = 1;
dfs1(to);
siz[u] += siz[to];
Siz[u] += Siz[to];
}
md += 2;
if (Siz[u] == siz[u]) return;
top = 0;
for (int j = 0; j < power[u].size(); j++) st[++top] = power[u][j];
for (int i = 1; i <= ndi; i++){
int v = nd[i];
for (int j = 0; j < power[v].size(); j++){
if (power[v][j] > d[v]) st[++top] = power[v][j] - d[v];
}
}
for (int i = 0; i <= siz[u]; i++) D[i] = 0;
for (int i = 1; i <= top; i++){
if (st[i] <= md){
D[0] += st[i];
D[1] += -1 - st[i];
D[st[i] + 1] += 1;
}
else {
D[0] += st[i];
D[1] += -1 - st[i];
}
}
for (int i = 1; i <= siz[u]; i++) D[i] += D[i - 1];
for (int i = 1; i <= siz[u]; i++) D[i] += D[i - 1];
ans[u] += D[0];
for (int i = 1; i <= ndi; i++) ans[nd[i]] += D[d[nd[i]]];
Redge(u) if (!vis[to = ed[k].to]){
if (siz[to] == Siz[to]) continue;
cal(to);
}
Redge(u) if (!vis[to = ed[k].to]){
if (siz[to] == Siz[to]) continue;
sum = Siz[to]; F[rt = 0] = INF;
getRT(to);
solve(rt);
}
}
int main(){
//double t = clock();
//freopen("1.in","r",stdin);
//freopen("a.out","w",stdout);
n = read(); m = read();
int pos,w;
for (int i = 2; i <= n; i++) build(i,read());
for (int i = 1; i <= m; i++){
pos = read(); w = read();
power[pos].push_back(w);
}
F[rt = 0] = INF; sum = n + m;
getRT(1);
solve(rt);
for (int i = 1; i <= n; i++) write(ans[i]);
//cerr << (clock() - t) / CLOCKS_PER_SEC << 's' << endl;
return 0;
}

雅礼培训4.3 Problem A 【点分治】的更多相关文章

  1. 雅礼培训 Problem B 【图论 + 贪心】

    题意 A和B在树上轮流选点,记A的联通块个数为\(x\),B的联通块个数为\(y\) A使\(x - y\)最大,B使\(x - y\) 二人采取最优策略,求\(x-y\) 题解 树联通块个数 = 点 ...

  2. 雅礼培训 Problem A 【线段树】

    题意 维护一段区间,支持求区间最大值,区间且,区间或 \(n,q<=2*10^5\) 题解 我们用线段树维护区间最大值 对于and和or运算, and实质就是强行把一些位改为0 or实质就是强行 ...

  3. Loj#6503-「雅礼集训 2018 Day4」Magic【分治NTT】

    正题 题目链接:https://loj.ac/p/6503 题目大意 \(n\)张卡\(m\)种,第\(i\)种卡有\(a_i\)张,求所有排列中有\(k\)对相邻且相同的卡牌. \(1\leq n\ ...

  4. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  5. 雅礼集训【Day6-1】字符串

    雅礼集训[Day6-1]字符串 假设我们有串\(a\),我们设\(a'\)为\(a\)翻转后按为取反过后的串. 我们只考虑前一半的,长为\(m\)的串.如果前半截匹配了\(a\)或者\(a'\),则\ ...

  6. 「雅礼集训 2017 Day7」事情的相似度

    「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...

  7. NOIP2018 模拟赛(二十二)雅礼NOI

    Preface 这次的题目都是NOI+的题,所以大家的分数都有点惨烈. 依靠T1大力骗分水到Rank2 所以想看正解的话看这里吧 A. 「雅礼NOI2018模拟赛(一) Day1」树 看一眼题目感觉十 ...

  8. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  9. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

随机推荐

  1. sysdig安装和使用介绍

    安装步骤1)安装资源库rpm --import https://s3.amazonaws.com/download.draios.com/DRAIOS-GPG-KEY.publiccurl -s -o ...

  2. License开源许可协议

    开源许可协议 License是软件的授权许可,表述了你获得代码后拥有的权利,可以对别人的作品进行何种操作,何种操作又是被禁止的. 开源许可证种类 Open Source Initiative http ...

  3. iOS打包上传app store各种问题解决总结

    问题1 this action could not be completed. try again 问题2 there was an error sending data to the iTunes ...

  4. Resize a UIImage the right way

    When deadlines loom, even skilled and experienced programmers can get a little sloppy. The pressure ...

  5. 自动发表QQ空间说说

    require("gb2312toutf8") local http = require "socket.http" local surl = "ht ...

  6. 一、新手必会Python基础

    博客内容: 1.基础语法 2.运算符 3.流程控制 4.列表.元组.字典.集合 5.字符串 6.文件操作 一.基础语法 1.标识符 命名规则: 以字母.下划线开头 其他部分由字母.数字或下划线组成 不 ...

  7. 拼凑json的实例

    一,拼凑  json 串 并传到后台 function writeToJson(num){ var i = 1; var jsonData = "["; for(i=1;i< ...

  8. OS复习

    提纲 一 操作系统的定义,各章节名词定义. 分时多道- OS四大特征,五大功能. 二 进程 创建终止挂起激活 PCB 原语:创建终止挂起激活唤醒 互斥和同步,临界资源,临界区 信号量的基础概念,受保护 ...

  9. Spring Boot -- Idea搭建下搭建web项目

    最近公司准备使用Spring Boot框架,让小瑾先来学习一下,为了表示小瑾的办事效率,小瑾直接先学习用Idea搭建一个Spring Boot项目,哈哈哈,坐等领导夸. 废话不多说了,先来总结一下用I ...

  10. Git学习——查看修改记录

    查看修改结果 修改之前commit的文件,输入下面的而命令,可以查看文件的改动,输入下面命令.还可以采用git diff命令来看看具体修改了什么. 如果确认无误,添加add和提交commit文件. g ...