当英雄能力值$ge 10^{7}$时,即能战胜所有敌人,简单预处理即可
若英雄能力值在$[2^{k},2^{k+1})$中,对敌人分类讨论:
1.若$s_{i}le 2^{k}$,其必然会战胜这些敌人
2.若$s_{i}>2^{k}$,考虑快速找到其第一次战胜这些敌人的时刻,注意到战胜这些敌人后,其能力值必然$ge 2^{k+1}$,那么至多发生$log 10^{7}$次(之后其能力值即$ge 10^{7}$)
下面,考虑用倍增来"快速找到其第一次战胜这些敌人的时刻",先假设对于所有第2类敌人其都会战败,在此情况下最小的差距,由此即可在$o(k)$的复杂度内找到该时刻
(假设初始能力值为0,且仍能战胜第1类敌人,也需要统计过程中能力值的增长)
由于空间问题,可以将范围修改为$[8^{k},8^{k+1})$,那么至多发生$8log 10^{7}$次
时间复杂度为$o(nlog^{2}n)$,可以通过
1 #include<bits/stdc++.h> 2 #include"dungeons.h" 3 using namespace std; 4 #define N 400005 5 #define L 24 6 #define LL 8 7 #define ll long long 8 int n,s[N],p[N],w[N],l[N],to[LL][N][L]; 9 ll tot[N],sum[LL][N][L],delta[LL][N][L]; 10 void init(int nn,vector<int>ss,vector<int>pp,vector<int>ww,vector<int>lll){ 11 n=nn; 12 for(int i=0;i<n;i++){ 13 s[i]=ss[i]; 14 p[i]=pp[i]; 15 w[i]=ww[i]; 16 l[i]=lll[i]; 17 } 18 for(int i=n-1;i>=0;i--)tot[i]=tot[w[i]]+s[i]; 19 for(int i=0;i<LL;i++){ 20 to[i][n][0]=n; 21 delta[i][n][0]=1e18; 22 for(int j=0;j<n;j++) 23 if (s[j]<=(1<<3*i)){ 24 to[i][j][0]=w[j]; 25 sum[i][j][0]=s[j]; 26 delta[i][j][0]=1e18; 27 } 28 else{ 29 to[i][j][0]=l[j]; 30 sum[i][j][0]=p[j]; 31 delta[i][j][0]=s[j]; 32 } 33 for(int j=1;j<L;j++) 34 for(int k=0;k<=n;k++){ 35 int x=to[i][k][j-1]; 36 to[i][k][j]=to[i][x][j-1]; 37 sum[i][k][j]=sum[i][k][j-1]+sum[i][x][j-1]; 38 delta[i][k][j]=min(delta[i][k][j-1],delta[i][x][j-1]-sum[i][k][j-1]); 39 } 40 } 41 } 42 ll simulate(int x,int yy){ 43 ll y=yy,time=0; 44 while ((x!=n)&&(y<(1<<L))){ 45 int k; 46 for(int i=0;i<LL;i++) 47 if (((1<<3*i)<=y)&&(y<(1<<3*i+3))){ 48 k=i; 49 break; 50 } 51 for(int i=L-1;i>=0;i--) 52 if (delta[k][x][i]>y){ 53 y+=sum[k][x][i]; 54 x=to[k][x][i]; 55 } 56 if (x!=n){ 57 y+=s[x]; 58 x=w[x]; 59 } 60 time++; 61 } 62 if (x!=n)y+=tot[x]; 63 return y; 64 } 65 int main(){ 66 freopen("1.in","r",stdin); 67 scanf("%*s"); 68 int n,m,x,y; 69 vector<int>s,p,w,l; 70 scanf("%d%d",&n,&m); 71 for(int i=1;i<=n;i++){ 72 scanf("%d",&x); 73 s.push_back(x); 74 } 75 for(int i=1;i<=n;i++){ 76 scanf("%d",&x); 77 p.push_back(x); 78 } 79 for(int i=1;i<=n;i++){ 80 scanf("%d",&x); 81 w.push_back(x); 82 } 83 for(int i=1;i<=n;i++){ 84 scanf("%d",&x); 85 l.push_back(x); 86 } 87 init(n,s,p,w,l); 88 printf("TRUE "); 89 for(int i=1;i<=m;i++){ 90 scanf("%d%d",&x,&y); 91 simulate(x,y); 92 } 93 }