题解

用一个平衡树维护能攻占到u点的骑士,合并到父亲的时候去掉攻击力小于父亲生命值的那部分,只要把那棵树拆掉并且将树中的所有骑士更新一下答案,用无旋式treap很好写

合并的时候只要启发式合并就可以了

复杂度\(O(n \log^2 n)\)

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 300005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
typedef unsigned int u32;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
u32 Rand() {
static u32 x = 20020421;
return x += x << 2 | 1;
}
struct Treap_node {
Treap_node *lc,*rc;
int siz,id;int64 val,mul,add;
u32 pri;
void addm(int64 v) {
val *= v;mul *= v;add *= v;
}
void addv(int64 v) {
val += v;add += v;
}
void push_down() {
if(mul != 1) {
if(lc) lc->addm(mul);
if(rc) rc->addm(mul);
mul = 1;
}
if(add) {
if(lc) lc->addv(add);
if(rc) rc->addv(add);
add = 0;
}
}
void update() {
siz = 1;
if(lc) siz += lc->siz;
if(rc) siz += rc->siz;
}
}pool[MAXN * 2],*tail = pool,*rt[MAXN],*que[MAXN];
int tot;
Treap_node *Newnode(int v,int id) {
Treap_node *res = tail++;
res->val = v;res->siz = 1;res->mul = 1;res->add = 0;
res->lc = res->rc = 0;res->pri = Rand();res->id = id;
return res;
}
void Split_val(Treap_node *u,Treap_node *&L,Treap_node *&R,int64 v) {
if(!u) {L = R = NULL;return;}
u->push_down();
if(u->val < v) {
L = u;
Split_val(u->rc,L->rc,R,v);
L->update();
}
else {
R = u;
Split_val(u->lc,L,R->lc,v);
R->update();
}
}
Treap_node *Merge(Treap_node *L,Treap_node *R) {
if(!L) return R;
if(!R) return L;
L->push_down();R->push_down();
if(L->pri > R->pri) {L->rc = Merge(L->rc,R);L->update();return L;}
else {R->lc = Merge(L,R->lc);R->update();return R;}
}
Treap_node* Insert(Treap_node *u,Treap_node *v) {
Treap_node *L,*R;
Split_val(u,L,R,v->val);
return Merge(Merge(L,v),R);
}
struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN],sumE,N,M;
int fa[MAXN],a[MAXN],dep[MAXN],ans1[MAXN],ans2[MAXN],c[MAXN];
int64 v[MAXN],s[MAXN],h[MAXN];
vector<int> kn[MAXN];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
void Init() {
read(N);read(M);
for(int i = 1 ; i <= N ; ++i) read(h[i]);
for(int i = 2 ; i <= N ; ++i) {
read(fa[i]);read(a[i]);read(v[i]);
add(fa[i],i);add(i,fa[i]);
}
for(int i = 1 ; i <= M ; ++i) {
read(s[i]);read(c[i]);
kn[c[i]].pb(i);
}
}
void get_tree(Treap_node *u) {
u->push_down();
if(u->lc) get_tree(u->lc);
que[++tot] = u;
if(u->rc) get_tree(u->rc);
}
void dfs(int u) {
Treap_node *L,*R;
dep[u] = dep[fa[u]] + 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa[u]) {
dfs(v);
Split_val(rt[v],L,R,h[u]);
if(L) {
ans1[u] += L->siz;
tot = 0;get_tree(L);
for(int j = 1 ; j <= tot ; ++j) ans2[que[j]->id] = dep[c[que[j]->id]] - dep[u];
}
if(R) {
if(R->siz > (rt[u] ? rt[u]->siz : 0)) swap(R,rt[u]);
if(!R) continue;
tot = 0;get_tree(R);
for(int j = 1 ; j <= tot ; ++j) {
que[j]->mul = 1;que[j]->add = 0;que[j]->lc = que[j]->rc = 0;que[j]->siz = 1;
rt[u] = Insert(rt[u],que[j]);
}
}
}
} int si = kn[u].size();
for(int i = 0 ; i < si ; ++i) {
if(s[kn[u][i]] >= h[u]) {
rt[u] = Insert(rt[u],Newnode(s[kn[u][i]],kn[u][i]));
}
else {ans2[kn[u][i]] = 0;ans1[u]++;}
}
if(rt[u]) {
if(a[u] == 0) rt[u]->addv(v[u]);
else rt[u]->addm(v[u]);
}
if(u == 1 && rt[u]) {
tot = 0;get_tree(rt[u]);
for(int j = 1 ; j <= tot ; ++j) ans2[que[j]->id] = dep[c[que[j]->id]];
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
dfs(1);
for(int i = 1 ; i <= N ; ++i) {out(ans1[i]);enter;}
for(int i = 1 ; i <= M ; ++i) {out(ans2[i]);enter;}
}

【LOJ】#2107. 「JLOI2015」城池攻占的更多相关文章

  1. 「JLOI2015」城池攻占 解题报告

    「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...

  2. 「JLOI2015」城池攻占 可并堆

    传送门 分析 如果直接暴力枚举的话肯定会超时 我们可以从下往上遍历,维护一个小根堆 每次到达一个节点把战败的骑士扔出去 剩下的再继续向上合并,注意要维护一下其实的战斗力 可以像线段树那样用一个lazy ...

  3. @loj - 2106@ 「JLOI2015」有意义的字符串

    目录 @description@ @solution@ @accepted code@ @details@ @description@ B 君有两个好朋友,他们叫宁宁和冉冉.有一天,冉冉遇到了一个有趣 ...

  4. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  5. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  6. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  7. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  8. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  9. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

随机推荐

  1. wamp安装失败原因大全

    wamp 是 Windos.Apache.Mysql.PHP集成安装环境 为了安装hdwiki 所以需要这个环境 1.下载wampserver_x86_3.0.6 64位  环境包,安装路径禁止有空格 ...

  2. 【刷题】洛谷 P4782 【模板】2-SAT 问题

    题目背景 2-SAT 问题 模板 题目描述 有n个布尔变量 \(x_1\)​~\(x_n\)​,另有m个需要满足的条件,每个条件的形式都是"\(x_i\)​为true/false或\(x_j ...

  3. 【题解】 [SDOI2009] Elaxia的路线(最短路+拓扑排序)

    懒得复制,戳我戳我 Solution: 题目大概意思就是找两条最短路后,找出最长公共部分 我们就只用以四个点为源点开始走\(SPFA\),然后我们就只用遍历每条边然后建立一个新的拓扑图,然后随便搞一下 ...

  4. mysql 分组取每个组的前几名的问题

    select *from hotel_addition_orders awhere (select count(*) from hotel_addition_orders where hotel_or ...

  5. [JZOJ 5402] God Knows

    终于搞完了这乡里别题目 $ $ 考虑一个 \(dp\) ,设 \(f[i]\) 表示最后一个匹配选 \((i,p[i])\) 的最小费用 首先我们考虑答案长什么样 假设根据 \(p[i]\) 排序 , ...

  6. 【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)

    [BZOJ1444][JSOI2009]有趣的游戏(高斯消元,AC自动机) 题面 BZOJ 题解 先把\(AC\)自动机构建出来,最好构成\(Trie\)图.然后这样子显然是在一个有向图中有一堆概率的 ...

  7. 【BZOJ1089】[SCOI2003]严格n元树(高精度,动态规划)

    [BZOJ1089][SCOI2003]严格n元树(高精度,动态规划) 题面 BZOJ 洛谷 题解 设\(f[i]\)表示深度为\(i\)的\(n\)元树个数.然后我们每次加入一个根节点,然后枚举它的 ...

  8. 【CF61D】Eternal Victory

    题目大意:给定一棵 N 个节点的树,求从 1 号节点(根节点)出发,任意节点结束,且至少经过每个节点一次的最短路径是多少. 题解:首先考虑最终要回到根节点的情况,可以发现最短路径长度一定等于该树边权的 ...

  9. C#代码连接Oracle数据库一段时间以后[connection lost contact]的问题

    最近在使用C#代码连接Oracle数据库,分为两部分,WCF的客户端与服务端.程序启动与运行都没有问题,部署到服务器上后,运行也没有问题.但是第二天再访问的时候,就会抛出下边所示的异常.这是怎么回事? ...

  10. 1: mysql left join,right join,inner join用法分析

    下面是例子分析表A记录如下: aID        aNum 1           a20050111 2           a20050112 3           a20050113 4   ...