好像所有人都写的左偏树 但我不会啊233

首先发现乘的时候 系数不会为负,所以能得到一个关键条件:变化后的战斗力随变化前的战斗力大小单调

所以我们考虑倍增

设hp[x][i]是从x开始一路攻克$2^i$个城池所需要最小的初始生命值

设trans[x][i][0/1]是攻克了$2^i$个城池后攻击力的变化量,0表示乘,1表示加,先乘后加

然后就可以倍增了

 #include<bits/stdc++.h>
#define pa pair<ll,ll>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
using namespace std;
typedef long long ll;
const int maxn=3e5+; inline char gc(){
return getchar();
static const int maxs=<<;static char buf[maxs],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,maxs,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd(){
ll x=;char c=gc();bool neg=;
while(c<''||c>''){if(c=='-') neg=;c=gc();}
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=gc();
return neg?(~x+):x;
} int N,M,fa[maxn][];
ll hp[maxn][],trans[maxn][][];
int ans1[maxn],ans2[maxn]; int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd(),M=rd();
for(i=;i<=N;i++) hp[i][]=rd();
fa[][]=N+;
for(i=;i<=N;i++){
fa[i][]=rd();
ll x=rd(),y=rd();
trans[i][][]=;
trans[i][][!x]=y;
for(j=;fa[i][j]&&fa[fa[i][j]][j];j++){
fa[i][j+]=fa[fa[i][j]][j];
hp[i][j+]=max(hp[i][j],(ll)ceil(1.0*(hp[fa[i][j]][j]-trans[i][j][])/trans[i][j][]));
trans[i][j+][]=trans[i][j][]*trans[fa[i][j]][j][]+trans[fa[i][j]][j][];
trans[i][j+][]=trans[i][j][]*trans[fa[i][j]][j][];
}
}
for(i=;i<=M;i++){
ll s=rd();int x=rd(),n=;
for(j=;j>=&&x!=-;j--){
if(fa[x][j]&&hp[x][j]<=s){
s=s*trans[x][j][]+trans[x][j][];
x=fa[x][j];
n+=<<j;
}
}
if(x!=-) ans1[x]++;
ans2[i]=n;
}
for(i=;i<=N;i++)
printf("%d\n",ans1[i]);
for(i=;i<=M;i++)
printf("%d\n",ans2[i]); return ;
}

好好分析空间啊kora!

然而空间大小恶意卡倍增

但是我们这个倍增可以换成三进制的2333

就是把定义里的$2^i$都换成$3^i$

于是$log_3300000=10$,空间就变成了原来的一半

需要注意的一点是,最后在跳倍增的时候,同一个长度可以跳两次(因为是三进制嘛),循环的时候稍微注意一下

 #include<bits/stdc++.h>
#define pa pair<ll,ll>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
using namespace std;
typedef long long ll;
const int maxn=3e5+; inline char gc(){
return getchar();
static const int maxs=<<;static char buf[maxs],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,maxs,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd(){
ll x=;char c=gc();bool neg=;
while(c<''||c>''){if(c=='-') neg=;c=gc();}
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=gc();
return neg?(~x+):x;
} int N,M,fa[maxn][];
ll hp[maxn][],trans[maxn][][];
int ans1[maxn],ans2[maxn];
int pw3[]; int main(){
//freopen("","r",stdin);
int i,j,k;
pw3[]=;for(i=;i<=;i++) pw3[i]=pw3[i-]*;
N=rd(),M=rd();
for(i=;i<=N;i++) hp[i][]=rd();
fa[][]=N+;
for(i=;i<=N;i++){
fa[i][]=rd();
ll x=rd(),y=rd();
trans[i][][]=;
trans[i][][!x]=y;
for(j=;j<;j++){
int f=fa[i][j],ff=fa[f][j];
if(!f||!ff||!fa[ff][j]) break;
fa[i][j+]=fa[ff][j];
ll hp1=max(hp[f][j],(ll)ceil(1.0*(hp[ff][j]-trans[f][j][])/trans[f][j][]));
hp[i][j+]=max(hp[i][j],(ll)ceil(1.0*(hp1-trans[i][j][])/trans[i][j][]));
trans[i][j+][]=trans[i][j][]*trans[f][j][]+trans[f][j][];
trans[i][j+][]=trans[i][j][]*trans[f][j][];
trans[i][j+][]=trans[i][j+][]*trans[ff][j][]+trans[ff][j][];
trans[i][j+][]=trans[i][j+][]*trans[ff][j][];
}
}
for(i=;i<=M;i++){
ll s=rd();int x=rd(),n=;
for(j=;j>=&&x!=-;j--){
if(fa[x][j]&&hp[x][j]<=s){
s=s*trans[x][j][]+trans[x][j][];
x=fa[x][j];
n+=pw3[j];j++;
}
}
if(x!=-) ans1[x]++;
ans2[i]=n;
}
for(i=;i<=N;i++)
printf("%d\n",ans1[i]);
for(i=;i<=M;i++)
printf("%d\n",ans2[i]); return ;
}

luogu3621 城池攻占 (倍增)的更多相关文章

  1. 【BZOJ】【4003】【JLOI2015】城池攻占

    可并堆 QAQ改了一下午……最终弃疗求助zyf……居然被秒了QAQ真是弱到不行(zyf太神了Orz) 还是先考虑部分分的做法: 1.$n,m\leq 3000$:可以暴力模拟每个骑士的攻打过程,也可以 ...

  2. BZOJ_4003_[JLOI2015]城池攻占_可并堆

    BZOJ_4003_[JLOI2015]城池攻占_可并堆 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 ...

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

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

  4. 【BZOJ4003】[JLOI2015]城池攻占 可并堆

    [BZOJ4003][JLOI2015]城池攻占 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号 ...

  5. [bzoj4003][JLOI2015]城池攻占_左偏树

    城池攻占 bzoj-4003 JLOI-2015 题目大意:一颗n个节点的有根数,m个有初始战斗力的骑士都站在节点上.每一个节点有一个standard,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...

  6. [洛谷P3261] [JLOI2015]城池攻占(左偏树)

    不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...

  7. BSOJ 4591 -- 【JLOI2015】城池攻占

    Description 小铭铭最近获得了一副新的桌游,游戏中需要用m个骑士攻占n个城池. 这n个城池用1到n的整数表示.除1号城池外,城池i会受到另一座城池fi的管辖,其中fi 每个城池有一个防御值h ...

  8. BZOJ 4003 【JLOI2015】城池攻占

    Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, ...

  9. 【BZOJ4003】【JLOI2015】城池攻占(左偏树)

    题面 题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其中 fi ...

随机推荐

  1. PAT L2-024 部落

    https://pintia.cn/problem-sets/994805046380707840/problems/994805056736444416 在一个社区里,每个人都有自己的小圈子,还可能 ...

  2. PAT L3-007 天梯地图

    https://pintia.cn/problem-sets/994805046380707840/problems/994805051153825792 本题要求你实现一个天梯赛专属在线地图,队员输 ...

  3. ES6学习之let

    块级作用域 ; i < ; i++){} console.log(i); ; j < ; j++){} console.log(j); //"ReferenceError: j ...

  4. mybatis数据源与连接池

    1.概念介绍1.1 数据源:顾名思义,数据的来源,它包含了数据库类型信息,位置和数据等信息,一个数据源对应一个数据库. 1.2 连接池:在做持久化操作时,需要通过数据库连接对象来连接数据库,而连接池就 ...

  5. vue二次实战

    vue爬坑之路 npm uninstall 模块名(删除指定模块) https://www.cnblogs.com/wisewrong/p/6255817.html vue快速入门 https://s ...

  6. MySQL5.5 安装配置方法教程

    MySQL下载地址:http://dev.mysql.com/downloads/installer/ 1.首先进入的是安装引导界面 2.然后进入的是类型选择界面,这里有3个类型:Typical(典型 ...

  7. 【译】Focused and Diffuse Modes(专注与发散模式)

    Focused and Diffuse Modes ---文章来源:coursera 面对一个问题,当无论如何都想不出办法时,你会怎么做呢?对于僵尸们来说,只需简单地不断用脑袋撞墙即可.然而活生生的大 ...

  8. Flutter 中 JSON 解析

    本文介绍一下Flutter中如何进行json数据的解析.在移动端开发中,请求服务端返回json数据并解析是一个很常见的使用场景.Android原生开发中,有GsonFormat这样的神器,一键生成Ja ...

  9. DAY08、文件操作

    一.文件操作模式汇总: 主模式: r:读模式 w:写模式(无创建,有清空) a:追加(有创建的功能) x:写,必须自己创建文件,否则报错 从模式: t:文本操作(默认模式)r >rt,w> ...

  10. python设计模式第二十三天【状态模式】

    1.应用场景 (1)通过改变对象的内部状态从而改变对象的行为,一般表现为状态的顺序执行 2.代码实现 #!/usr/bin/env python #!_*_ coding:UTF-8 _*_ from ...