Codeforces 1458E - Nim Shortcuts(博弈论+BIT)
首先看到这样的题我们不妨从最特殊的情况入手,再逐渐推广到一般的情况。考虑如果没有特殊点的情况,我们将每个可能的局面看作一个点 \((a,b)\) 并映射到坐标系上。考虑按照博弈论的套路求出每个点是必胜点还是必输点,就这题而言,显然一个点 \((x,y)\) 是必胜点当且仅当 \(\exists z<x\) 满足 \((z,y)\) 是必胜点或者 \(\exists z<y\) 满足 \((y,z)\) 是必胜点。打个表 即可知道一个状态 \((x,y)\) 为 P 态(必输点)当且仅当 \(x=y\),否则该状态为 N 态(必胜点)。这个异常好理解,如果 \(x=y\) 那不论先手取了多少石子,后手都可以在另一堆中取相同数量的棋子,最终肯定会留给先手一个 \((0,0)\) 的局面。
紧接着我们考虑有一个特殊点的情况,我们假设这个特殊点为 \((x,y)\),那么可以分出三种情况:
\(x=y\),那么这个点本来就是 P 态,显然不会对每个点的 N/P 态产生任何影响
\(x>y\),如图所示,假设该点为 \(P\),那么该点在直线 \(y=x\) 的右下方。显然该点不会对该点左边及下方的点的状态产生影响,也就是说产生直接影响的只可能是 \(P\) 沿 \(+x\) 方向引出的射线(图中的黄色射线)或沿 \(+y\) 方向引出的射线(图中的橙色射线),将这些点全都变成 N 态。而显然黄色射线上的所有点本来就是 N 态,橙色射线上的点除了其与 \(y=x\) 的交点其他也都是 N 态,故这个点产生的效果是将橙色射线与 \(y=x\) 的交点 \((x,x)\) 变为 N 态,但这样会带来一个副作用,那就是 \((x,x)\) 变为 N 态了,\((x+1,x)\) 反而无法直接到达 N 态的点,变成 P 态了,按照类似的方式归纳也可知道这样会导致 \((x+2,x+1),(x+3,x+2),\cdots,(k+1,k)\) 变为 P 态,即图中的红色部分为 P 态,其余为 N 态。

\(x<y\),与 \(x<y\) 的情况类似,只不过变成 \((y,y)\) 变为 N 态,\((y,y+1),(y+1,y+2),\cdots\) 变为 P 态。
\(n\le 1\) 的情况已经解决了,那么怎样解决原题呢?
注意到题目有个显然的性质就是每行每列中除特殊点外最多一个 P 点,也就是说每列除特殊点外的 P 点组成的函数是一个分段函数,并且每段都是一个形如 \(y=x+k\) 的函数,比方说下图:

我们考虑重新观察一下上面每个关键点的作用效果。对于每个向上引出射线的关键点(例如图中的 \(P_1\)),我们可以近似地看作删除了该关键点所在的列并将左右两部分重新拼在一起,对于每个向右引出射线的关键点我们也可近似地看作删除了该关键点所在的行,这样一来思路就来了,我们将所有关键点按横坐标从小到大排序,对于一个关键点 \((x,y)\),我们记 \(s\) 为 \(x\) 前面有多少列被删除,\(t\) 为 \(y\) 前面有多少行被删除,那么该关键点所在部分 P 态的点的函数表达式就是 \(y=x+s-t\),我们按照线性规划的思想将这个点与这条线的关系进行比较,如果 \(y<x+s-t\) 那么该点应当向上引出射线,即删除这一列,那么我们只需令 \(s\) 加一,注意如果这一列已经删除了就不用再删了。如果 \(y=x+s-t\) 那么该点可以直接忽略,如果 \(y>x+s-t\) 那么应当删除这一行。最后考虑回答每个询问,首先特判掉待询问点与某个关键点重合的情况,此时答案显然为 LOSE,其次如果存在某个关键点与待询问点同行同列,那么答案显然是 WIN,否则我们还是求出 \(s\) 表示 \(x\) 前面有多少列被删除,\(t\) 表示 \(y\) 前面有多少行被删除,并检验 \((x,y)\) 是否在 \(y=x+s-t\) 上即可。求 \(t\) 可以采用离散化+树状数组。
时间复杂度 \(n\log n\)。
const int MAXN=1e5;
int n,m;
struct event{
int x,y,id;
bool operator <(const event &rhs) const{
if(x!=rhs.x) return x<rhs.x;
else if(y!=rhs.y) return y<rhs.y;
return id<rhs.id;
}
} a[MAXN*2+5];
int key[MAXN*2+5],uni[MAXN*2+5],cnt=0,num=0;
int get(int x){return lower_bound(uni+1,uni+num+1,x)-uni;}
bool is[MAXN*2+5],ans[MAXN+5];int c1=0,lst=0;
int t[MAXN*2+5];
void add(int x){for(int i=x;i<=num;i+=(i&-i)) t[i]++;};
int query(int x){int ret=0;for(int i=x;i;i&=(i-1)) ret+=t[i];return ret;}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y),key[++cnt]=a[i].y;
for(int i=1;i<=m;i++) scanf("%d%d",&a[i+n].x,&a[i+n].y),a[i+n].id=i,key[++cnt]=a[i+n].y;
sort(a+1,a+n+m+1);sort(key+1,key+cnt+1);key[0]=-1;
for(int i=1;i<=cnt;i++) if(key[i]!=key[i-1]) uni[++num]=key[i];
for(int i=1;i<=n+m;i++){
int pos=get(a[i].y);
if(a[i].id){
if(a[i-1].x==a[i].x&&a[i-1].y==a[i].y) ans[a[i].id]=1;
else if(a[i].x!=lst&&!is[pos]){
int dif=query(pos)-c1;
// printf("%d\n",dif);
if(a[i].y==a[i].x+dif) ans[a[i].id]=1;
}
} else {
int dif=query(pos)-c1;
if(a[i].x+dif<a[i].y){//up
if(!is[pos]) add(pos),is[pos]=1;
} else if(a[i].x+dif>a[i].y){//down
if(lst!=a[i].x) lst=a[i].x,c1++;
}
}
}
for(int i=1;i<=m;i++) printf("%s\n",(ans[i])?"LOSE":"WIN");
return 0;
}
Codeforces 1458E - Nim Shortcuts(博弈论+BIT)的更多相关文章
- 【HDU3032】Nim or not Nim?(博弈论)
[HDU3032]Nim or not Nim?(博弈论) 题面 HDU 题解 \(Multi-SG\)模板题 #include<iostream> #include<cstdio& ...
- CodeForces - 1162E Thanos Nim (博弈论)
Alice and Bob are playing a game with nn piles of stones. It is guaranteed that nn is an even number ...
- BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基
一个原来写的题. 既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜. 所以思考一下我们要在第一回合留下线性基 然后就是求线性基,因为要取走的最少,所以排一 ...
- POJ2975 Nim 【博弈论】
DescriptionNim is a 2-player game featuring several piles of stones. Players alternate turns, and on ...
- HDU.3032.Nim or not Nim?(博弈论 Lasker's Nim)
题目链接 \(Description\) 有多堆石子, 每次可以将任意一堆拿走任意个或者将这一堆分成非空的两堆, 拿走最后一颗石子的人胜利.问谁会获得胜利. \(Solution\) Lasker's ...
- 2018.09.25 poj2068 Nim(博弈论+dp)
传送门 题意简述:m个石子,有两个队每队n个人循环取,每个人每次取石子有数量限制,取最后一块的输,问先手能否获胜. 博弈论+dp. 我们令f[i][j]f[i][j]f[i][j]表示当前第i个人取石 ...
- POJ 2975 Nim(博弈论)
[题目链接] http://poj.org/problem?id=2975 [题目大意] 问在传统的nim游戏中先手必胜策略的数量 [题解] 设sg=a1^a1^a3^a4^………^an,当sg为0时 ...
- Codeforces 786A Berzerk(博弈论)
[题目链接] http://codeforces.com/problemset/problem/786/A [题目大意] 有两个人,每个人有一个数集,里面有一些数,现在有一个环,有个棋子放在1, 有个 ...
- Leetcode 292 Nim Game 博弈论
class Solution {public: bool canWinNim(int n) { return n % 4 != 0; }};
随机推荐
- SpringCloud微服务实战——搭建企业级开发框架(二):环境准备
这里简单说明一下在Windows系统下开发SpringCloud项目所需要的的基本环境,这里只说明开发过程中基础必须的软件,其他扩展功能(Docker,k8s,MinIO,XXL-JOB,EKL,Ke ...
- Tekton+Argocd实现自动化流水线
目录 什么是tekton 安装tekton 安装Dashboard Tekton提供的CRD 安装argocd 创建argocd 安装客户端 连接argocd server 创建App 集群中查看效果 ...
- Scrum Meeting 1补充会议
日期:2021年04月24日 会议主要内容概述: 本次会议于11:30举行,对项目架构做出了重要调整,并根据该调整修改了第1次例会报告中后两日计划完成的工作部分. 一.架构调整 会上讨论了用户模块相关 ...
- EFCore_环境搭建与简单使用_01
开发环境搭建 经典步骤:建实体类.建DbContext.生成数据库 本次使用codefirst模式,走下流程,(你也可以先建好数据库,用命令行的形式,直接生成DbContext,而且生成的DbCont ...
- STP生成树协议在二层环境中的应用
一 STP简介 1.单词: rstp快速生成树协议 filter过滤 protection保护 2.作用: 通过阻塞特定接口来防止二层交换环路,从而做到既可以提高网络可靠性的同时又能避免环路带来的问题 ...
- PHP笔记4__函数/全局、静态变量/函数参数/加载函数库/,,
<?php header("Content-type: text/html; charset=utf-8"); echo table(5,5); function table ...
- 【网络好文】---MySQL为Null导致的四大坑
正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如所示: select version(); -- 版本为 8.0.22 "兵马未动粮草先行",看完了相关的配置之 ...
- ESXi 6.7 的https服务挂掉处理方法 503 Service Unavailable
首先进入EXSi开启SSH(ESXi的主机控制台,非web控制台,是安装esxi的控制台) 然后 /etc/init.d/hostd status 显示已停止, 使用 /etc/init.d/host ...
- Java的基本数据类型和数据类型转换
首先java属于强类型语言,要求变量的使用要严格遵守规范,所有变量都必须先定义后才能使用. Java的数据类型分为以下两种: 1 基础数据类型(primtive type) 和 2 引用数据类型(re ...
- springmvc学习笔记(全)
SpringMVC简介 什么是MVC MVC是一种软件架构的思想,将软件按照模型.视图.控制器来划分 M: Model:模型层,指工程中的JavaBean,作用是处理数据.JavaBean分为两类: ...