首页 > 其他分享 >P9730 [CEOI2023] Grading Server

P9730 [CEOI2023] Grading Server

时间:2025-01-18 16:20:53浏览次数:1  
标签:F1 F2 A1 int Server P9730 CEOI2023 蓄力 A2

这是什么神仙题啊。

本题主要思路:优化转移决策,减少 dp 状态。

我们发现减一层盾其实就是给自己加攻击,所以我们将初始生命值(攻击力) \(C_H\) 和 \(C_G\) 重新表示为 \(A_1 = C_H - f_G S\),\(A_2 = C_G - f_H S\),让 \(F_1 = f_G\),\(F_2 = f_H\)。

现在的点对就是 \((A_1,F_1,A_2,F_2)\),容易发现每一维都是存在单调性的,若 \((A_1,F_1,A_2,F_2)\) 先手胜,\((A_1 + 1,F_1,A_2,F_2)\) 一定也是先手胜。

然后我们考虑减少 dp 状态。

为方便叙述,我们称破一层盾为蓄力,设 \(M = \max(A_1,F_1,A_2,F_2)\)。


首先我们能够粗略发现有些情况下决策是固定的。

  • 当 \(A_1 \ge S \wedge A_2 \le S\) 时,先手必胜,因为先手只要攻击就一定能使后手攻击力小于 \(0\)。

  • 当 \(A_1 \ge 0 \wedge A_2 \le 0 \wedge F_1 > 0\) 时,蓄力就能得到第一种情况。

  • 当 \(A_1 \le 0\) 时,一定选择蓄力。

  • 当 \(A_2 \ge S\) 时,先手一定选择攻击,因为若蓄力,后手攻击就一定会让你的蓄力次数和攻击力都减少,显然不优。

而这些就让 \(A_1,A_2 \in [0,S]\),\(F_1,F_2 \in [0,M/S]\) 了,大大减少了 dp 状态。


然后我们还能发现,当 \(A_1,A_2 \in [0,S]\),若先手总是蓄力,那后手一定得攻击先手,所以又有了这么一个限制 (\(d_1 = S - A_2\),\(d_2 = S - A_1\)):

  • 当 \(A_1 + d_1 F_1 \ge S\) 时,先手必胜。

对应的,若我们要使 \((A_1,F_1,A_2,F_2)\) 这个点对是有用的,我们还要让后手 \(A_2\) 满足:

  • \(A_2 - A_1 + d_2 F_2 \le S\)

所以若 \(A_2 - (A_1 + F_1 d_1) + (d_2 - F_1 d_1) F_2 \ge S\),后手必胜,不然先手就要将后手操作到 \(A_2 - A_1 + d_2 F_2 \le S\) 为止。

这时候 dp 状态又多了限制: \(d_1 F_1 \le S - A_1 = d_2\), \(d_2 F_2 \le S + A_1 - A_2\),大致状态数就是 \(S^2\) 再多个对数。


那如果不蓄力,而是攻击呢。具体来说,就是先手先蓄力 \(x\) 轮 \(\to\) 先手攻击后手,后手蓄力 \(\to\) 后手攻击先手,先手蓄力。

那用式子写出来?(\(A_{1/2}^{'}\) 表示先手/后手最后的攻击力,\(d_{1}^{'}\) 同理)

\(max(A_{2}^{'})\)

$= A_2 - (A_1 + x d_1) + (d_2 - x d_1) F_2 $

\(= (A_2 - A_1 + d_2 F_2) - x d_1 (F_2 + 1) \le S - x d_1 (F_2 + 1)\)

所以 \(d_{1}^{'} \ge x d_1 (F_2 + 1)\)。

那再蓄力就能使攻击力至少加 \((F_2 +1) d_1 x(F_1 - x)\),若令 \(x = \frac{F_1}{2}\),那就至少加 \(\frac{1}{4}(F_2 +1) d_1 F_1^2\)。

由于后手攻击了先手一次,但 \(A_2^{'} \le S\),所以只要 \(\frac{1}{4}(F_2 +1) d_1 F_1^2 \ge 2S\),先手必胜。

所以又有了 \((F_2 +1) d_1 F_1^2 \le 8S\) 的限制,这下状态数就只剩 \(S\) 多个对数了,时间复杂度就可以接受了。

点击查看代码
#include<bits/stdc++.h>
#define fir first
#define sec second
#define int long long
#define mkp make_pair
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> pir;
inline int read(){
    int x=0,f=1; char c=getchar();
    while(!isdigit(c)){if(c=='-') f=-1; c=getchar();}
    while(isdigit(c)){x=x*10+(c^48); c=getchar();}
    return x*f;
}
map<tuple<int,int,int>,int> mp;
int S;
inline bool dfs(int A1,int F1,int A2,int F2){
    
    int fl=0;
    while(1){
        if(F1*S+A1<=0) return fl;
        if(F2*S+A2<=0) return !fl;
        if(A1>=S&&A2<=S) return !fl;
        if(F1&&(A1>=0&&A2<=0)) return !fl;
        if(A2>=S||!F1){
            A2-=A1; fl=!fl;
            swap(A1,A2),swap(F1,F2);
            continue;
        }
        if(A1<=0){
            if(!F2&&A2<S){
                int nd=(-A1)/(S-A2)+1;
                if(nd>F1) return fl;
                A1+=(S-A2)*nd,F1-=nd;
                continue;
            }
            int nd1=(-A1+S-1)/S;
            int nd2=0; if(A2<=0) nd2=(-A2+S-1)/S;
            int stp=min(nd1,nd2);
            stp=max(stp-1,0ll);
            A1+=(stp+1)*S,F1-=(stp+1);
            A2+=stp*S,F2-=stp;
            fl=!fl;swap(A1,A2),swap(F1,F2);
            continue;
        }
        
        int d1=S-A2,d2=S-A1;
        if(A1+d1*F1>=S) return !fl;
        if(d2*F2>=S-A2+A1){
            int t=(d2*F2+A2-A1-S)/(F2+1)/d1+1;
            if(t>F1) return fl;
            A1+=t*d1,F1-=t;
            continue;
        }
        if(F1!=1&&(max({F2+1,d1,F1})>=8*S||(F2+1)*d1*F1*F1>=8*S)) return !fl;
        if(mp.find({F1,A2,F2})!=mp.end()) return fl^(A1>=mp[{F1,A2,F2}]);
        
        int l=0,r=S,res=r;
        while(l<=r){
            int mid=(l+r)>>1;
            if(dfs(A2,F2,mid+S,F1-1)&&dfs(A2-mid,F2,mid,F1)) l=mid+1;
            else r=mid-1,res=mid;
        }
        mp[{F1,A2,F2}]=res;
        return fl^(A1>=res);
    }
    
    
}
int c1,c2,f1,f2;
inline void solve(){
    c1=read(),f1=read(),c2=read(),f2=read();
    c1-=f2*S,c2-=f1*S;
    puts(dfs(c1,f2,c2,f1)?"YES":"NO");
}
signed main(){
    S=read();
    int T=read();
    while(T--) solve();
}
/*
1 1
1000000000000 0 1 1000000000000
*/

标签:F1,F2,A1,int,Server,P9730,CEOI2023,蓄力,A2
From: https://www.cnblogs.com/Cyan0826/p/18678519

相关文章

  • 阿里云 Serverless 助力盟主直播:高并发下的稳定性和成本优化
    在直播场景中,阿里云Serverless应用引擎SAE提供的无缝弹性伸缩与极速部署能力,确保直播间高并发时的流畅体验,降低了我们的运营成本,简化了运维流程。结合阿里云云原生数据库PolarDB的Serverless能力,实现了数据库资源按需自动扩展,在优化成本的同时极大增强了业务灵活性和响应......
  • SQL Server 内存占用高分析及解决办法(超详细)
    SQLServer内存占用高分析及解决办法(超详细)一、问题1.1、SQLServer内存占用高,内存不释放1.2、SQLServer内存使用策略SQLServer对服务器内存的使用策略是有多少占多少(大约到剩余内存为4M左右)只用在服务器内存不足时,才会释放一点占用的内存,所以很多时候,我们会发现运行SQ......
  • Winserver用指令批量添加修改AD域控用户.210702
    实践证明,批处理啥的,真的没有ExcelVlookup快。做以下步骤前,记得用好Excel,用公式把内容拼接好,然后愉快地玩耍。1.查找现在OU下的所有用户dsqueryuserou=ZTGM,dc=zt,dc=com-limit0>1.txt2.新增用户:dsadduser指令dsadduser"CN=叶是,OU=采购中心,OU=ZTGM,DC=zt,DC=com"......
  • 使用 wx-server-sdk
    在云函数中使用wx-server-sdk云函数属于管理端,在云函数中运行的代码拥有不受限的数据库读写权限和云文件读写权限。需特别注意,云函数运行环境即是管理端,与云函数中的传入的openId对应的微信用户是否是小程序的管理员/开发者无关。云函数中使用wx-server-sdk需在对应云函......
  • sql server 每个表占用大小查询【转】
    SQLServer查看库、表占用空间大小 目录1.查看数据文件占用(权限要求较大)2.查看日志文件占用sqlserver查看所有表大小、所占空间基于T-SQL 转自:https://blog.csdn.net/yenange/article/details/50493580查询数据文件与日志文件占用情况,查看数据大小,查看库大......
  • 如何解决SQL Server数据库版本过低的问题?
    关于您提到的SQLServer数据库版本过低的问题,我们理解这对您的业务运营带来了不便。为了帮助您顺利升级数据库版本,以下是详细的解决方案:备份现有数据:在进行任何升级操作之前,务必备份所有重要数据。可以通过SQLServerManagementStudio(SSMS)或其他备份工具导出数据库为.sql......
  • Prometheus Server一键部署脚本
    一.PrometheusServer一键部署脚本脚本内容展示[root@prometheus-server31~]#catinstall-prometheus-server.sh#!/bin/bash#auther:almco#blog:https://www.cnblogs.com/yinzhengjieVERSION=2.53.2ARCH=amd64SOFTWARE=prometheus-${VERSION}.linux-${ARCH}.ta......
  • 如何解决使用 SQL Server 管理器远程操作数据库时出现“索引超出了数组界限 (Microsof
    问题描述当您使用SQLServerManagementStudio(SSMS)远程连接并操作数据库时,可能会遇到以下错误提示:“索引超出了数组界限(Microsoft.SqlServer.Smo)”。这个错误通常发生在尝试执行某些特定操作(如查询、修改表结构等)时。该问题不仅影响工作效率,还可能导致数据操作失败。错......
  • JS MutationObserver监听DOM元素改变
    JSMutationObserver监听DOM元素改变://目标容器constchatSection=document.querySelector('section.chat');if(!chatSection){console.error('未找到容器');}else{//解析详细数据的函数functionparseChatData(){console.log('解析到的......
  • 批量删除SQL Server数据库指定ID范围的数据
    在SQLServer中,可以通过编写SQL语句来删除指定ID范围内的数据。以下是具体的SQL语句示例:删除ID大于1000的数据:sql DELETEFROM[数据库名].[数据库表]WHEREID>1000;删除ID小于1000的数据:sql DELETEFROM[数据库名].[数据库表]WHEREID<1000;解释......