题目简述

一个\(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. vijos 1524 最小监视代价

    背景 看到Vijos上此类型的题目较少,特地放一道上来给大家练练. 描述 由于yxy小朋友做了一些不该做的事,他被jzp关进了一个迷宫里.由于jzp最近比较忙,疏忽大意了一些,yxy可以在迷宫中任意走 ...

  2. ubuntu 16.04 国内源安装docker

    1. 通过curl命令安装 检查是否安装curl root@ros-OptiPlex-3050:~# which curlroot@ros-OptiPlex-3050:~# 更新安装 root@ros ...

  3. SAP成都研究院飞机哥:程序猿和飞机的不解之缘

    今天的文章来自Jerry的老同事张航. 张航和Jerry一样于2007年毕业后加入SAP成都研究院工作至今.进入SAP后的第一个开发部门是SAP Business by Design Infrastr ...

  4. 机器学习(3)- 学习建议<误差出现如何解决?>

    根据Andrew Ng在斯坦福的<机器学习>视频做笔记,已经通过李航<统计学习方法>获得的知识不赘述,仅列出提纲. 1 学习建议 误差太大,如何改进? 使用更多的训练样本→解决 ...

  5. Node.js连接mysql报加密方式错误解决方案

    本人在学习全栈开发过程中做一个Node的web项目在连接本地MySQL8.0版本的数据库时,发现Navicat连接不上,它报了一个数据库的加密方式导致连接不上的错误,错误如下: MySQL8.0版本的 ...

  6. 国庆集训 || Wannafly Day4

    链接:https://www.nowcoder.com/acm/contest/205#question 一场题面非常 有趣 但是题目非常 不友好的比赛 QAQ L.数论之神   思维(?) 题意:求 ...

  7. selenium--Xpath定位

    前戏 前面介绍过了七种定位方式,今天来介绍最后一种,也是最强大,本人最常用的定位方式xpath Xpath 即为 xml 路径语言,它是一种用来确定 xml 文档中某部分位置的语言.Xpath 基于 ...

  8. HTML5 Geolocation(地理位置)

    HTML5 Geolocation(地理位置).是用来定位用户的位置的. HTML5 Geolocation API 用于获得用户的地理位置,鉴于该特性可能侵犯用户的隐私权,除非用户同意,否则不能获取 ...

  9. Spring框架针对dao层的jdbcTemplate操作crud之query查询数据操作 —— 查询表,返回结果为对象的list集合

    用JdbcTemplate的方法完成, 查询数据库表,把用户表sw_user所有数据以List<User>集合返回 在JdbcTemplateDemo类中增加查询返回所有对象集合的方法qu ...

  10. OAuth授权之回调accessToken

    具体说明见新浪官方文档 http://open.weibo.com/wiki/Oauth2/access_token   具体实现 第一步 打开回调页面 // 宏定义client_id #define ...