• [loj3527]地牢游戏


    当英雄能力值$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 }
    View Code

  • 相关阅读:
    transform 多值先后执行顺序
    css 清除浮动
    鼠标移动到图片,图片放大
    js 事件循环机制EventLoop
    web安全
    web前端踩坑记录
    滚动加载图片(懒加载)
    css 兼容问题
    模块化 AMD与CMD 规范
    css 盒子模型 ie盒子模型
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15003022.html
Copyright © 2020-2023  润新知