好像所有人都写的左偏树 但我不会啊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. Java使用Redis实现分布式锁来防止重复提交问题

    如何用消息系统避免分布式事务? - 少年阿宾 - BlogJavahttp://www.blogjava.net/stevenjohn/archive/2018/01/04/433004.html [ ...

  2. XManager&XShell如何保存登录用户和登录密码

    Xshell配置ssh免密码登录 - qingfeng2556的博客 - CSDN博客https://blog.csdn.net/wuhenzhangxing/article/details/7948 ...

  3. Azure系列2.1.13 —— CloudBlockBlob

    (小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...

  4. CentOS7安装Jenkins,使用war方式直接运行或用yum方式安装运行

    jenkins最简单的安装方式呢,就是直接去官网下载jenkins的war包,把war丢到tomcat里运行,直接就能打开了. Jenkins官网:https://jenkins.io/downloa ...

  5. Day 5-3 多态与多态性

    多态与多态性 鸭子类型 多态与多态性 多态:一类事物有多种形态.比如,动物有多种形态,人,狗,猪,豹子.水也有多种形态,冰,雪,水蒸气. #多态:同一类事物的多种形态 import abc class ...

  6. Code::Blocks debug程序

    设置Settings--->Compiler, 打上勾: Produce debugging symbols [-g] 需要在settings->debugger settings-> ...

  7. python 编码格式

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...

  8. linux 挂载windows下目录,其它linux机器nfs的目录,自己dd的文件

    如有转载,不胜荣幸.http://www.cnblogs.com/aaron-agu/ 挂载window下共享的目录 //192.168.0.11/share /mnt 挂载其它linux机器下目录 ...

  9. QTP 自动货测试桌面程序-笔记(添加控件仓库并关联到action)

    录制或编写脚本前先添加行为对应的控件仓库: 心得:多个测试action使用的同一个窗体的仓库单独放于一个仓库中,可以在多个action中添加关联使用 将同一个窗体的控件只放于一个仓库中,减少使用时的名 ...

  10. Vue之双向数据绑定

    demo.html <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/19 ...