Codeforces Round 972 (Div. 2) E2. Subtangle Game (Hard Version)(博弈+双指针 sg函数思想)

news2024/9/23 6:51:17

题目

思路来源

稲葉廻代码

题解

这个题比easy version的数据范围大了比较多,

不能再直接dp[i][j][k]表示数组a的第i个做开始局面时,位置(j,k)为起点时的获胜情况了

当然你把第一维压到bitset里,然后前缀和优化一下,还是可以通过的,这里先不讨论这个方法

期望dp和博弈都类似dag,都可以考虑从终态局面往回推,

那么对于序列a的最后一个元素,考虑所有获胜位置,

就是每行的最靠右,且其右下方没有与之相同元素的位置

如果一行内出现了两个相同元素,选左边的那个肯定是不优的,

给对手的下一步留了更多的操作空间(选右边的那个时下一步的操作空间是选左边的真子集)

对于所有颜色v都处理出这样的位置集合,记为win[v],表示v作为最后一步时的所有获胜位置

这个位置序列,是一个第一维增序,第二维降序的序列,形如(1,4)(2,3)(3,2)这种

然后考虑倒着遍历a数组,求出最后一步win[a[l]]了之后,

考虑求出倒数第二步win[a[l-1]]的所有获胜位置,

只要能走到win[a[l]]内任意一个元素的都是必败的,否则就是必胜的

这个用双指针维护,

一个指针控制第一维,找到下一个vector内第一维比当前位置(x,y)第一维大的最右右端点r,

另一个指针控制第二维,找到下一个vector内第一维比当前位置(x,y)第二维大的最小左端点l,

那么,如果l<=r且[l,r]内有下一个vector内必胜(sg=1)的元素,当前局面就必败(sg=0)

反过来,则必胜(sg=1)

逆推到第一个元素,然后判断第一个元素对应的vector内是否有必胜元素即可

这题主要时间花在读入上了,scanf 2s交c++20直接T了,交c++17少了一点时间AC了

c++20对关同步cin有特殊优化,导致关同步cin比scanf快,但是快读还是最快的,1s不到

代码

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<array>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
//#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
namespace fastIO
{
    static char buf[100000],*h=buf,*d=buf;//缓存开大可减少读入时间,看题目给的空间
    #define gc h==d&&(d=(h=buf)+fread(buf,1,100000,stdin),h==d)?EOF:*h++//不能用fread则换成getchar
    template<typename T>
    inline void sci(T&x)
    {
        int f = 1;x = 0;
        register char c(gc);
        while(c>'9'||c<'0'){
            if(c == '-') f = -1;
            c=gc;
        }
        while(c<='9'&&c>='0')x=(x<<1)+(x<<3)+(c^48),c=gc;
        x *= f;
    }
    template<typename T>
    void output(T x)
    {
        if(x<0){putchar('-');x=~(x-1);}
        static int s[20],top=0;
        while(x){s[++top]=x%10;x/=10;}
        if(!top)s[++top]=0;
        while(top)putchar(s[top--]+'0');
    }
}
using namespace fastIO;
const int N=1505;
int t,l,n,m,a[N],b[N][N],sg[N],nsg[N],mn[N*N];
vector<P>win[N*N];
void sol(){
    sci(l);sci(n);sci(m);
    rep(i,1,l){
        sci(a[i]);
    }
    rep(i,1,n){
        rep(j,1,m){
            sci(b[i][j]);
        }
    }
    rep(i,1,n*m)win[i].clear(),mn[i]=0;
    per(i,n,1){
        per(j,m,1){
            int v=b[i][j];
            if(j>mn[v]){
                win[v].pb(P(i,j));
                mn[v]=j;
            }
        }
    }
    memset(sg,0,sizeof sg);
    memset(nsg,0,sizeof nsg);
    per(i,l,1){
        vector<P>&now=win[a[i]],&nex=win[a[i+1]];
        int p=SZ(now),q=(i==l?0:SZ(nex)),l=0,r=-1;
        rep(j,0,p-1){
            P v=now[j];
            while(r+1<q && nex[r+1].fi>v.fi)r++;//[0,r] >v.fi
            while(l<q && nex[l].se<=v.se)l++;//[l,q) >v.se
            nsg[j+1]=(sg[r+1]-sg[l]<=0);//[l,r]
        }
        sg[0]=nsg[0],nsg[0]=0;
        rep(j,1,p)sg[j]=sg[j-1]+nsg[j],nsg[j]=0;
        if(i==1){
            printf("%c\n","NT"[sg[p]>0]);
            return;
        }
    }
}
int main(){
    sci(t);
    while(t--){
        sol();
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2156920.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中序遍历二叉树全过程图解

文章目录 中序遍历图解总结拓展&#xff1a;回归与回溯 中序遍历图解 首先看下中序遍历的代码&#xff0c;其接受一个根结点root作为参数&#xff0c;判断根节点是否为nil&#xff0c;不为nil则先递归遍历左子树。 func traversal(root *TreeNode,res *[]int) {if root nil …

Tomcat中间件常见漏洞复现

#1.CVE-2017-12615 -----Tomcat put方法任意文件写入漏洞 1.打开靶场 cd vulhub/tomcat/CVE-2017-12615 docker-compose up -d docker ps 2.访问8080端口&#xff0c;来到靶场 3.首页进抓包&#xff0c;Tomcat允许适⽤put⽅法上传任意⽂件类型&#xff0c;但不允许jsp后缀…

redisson 延迟队列实现任务过期监听

一、需求&#xff1a; 任务超过一个小时以后&#xff0c;如果还为待执行状态&#xff0c;则自动转为结束状态。 二、实现: 创建延迟队列的监听任务RedisDelayedQueueListener&#xff0c;消费延迟队列&#xff1b;创建新增延迟队列的类&#xff0c;用于创建延迟队列&#xf…

LeetCode 热题 100 回顾17

干货分享&#xff0c;感谢您的阅读&#xff01;原文见&#xff1a;LeetCode 热题 100 回顾_力code热题100-CSDN博客 一、哈希部分 1.两数之和 &#xff08;简单&#xff09; 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标…

HTML翻牌器:用CSS和HTML元素创造动态数字展示

HTML翻牌器&#xff1a;用CSS和HTML元素创造动态数字展示 前言 翻牌器是一种数字动态展示形式&#xff0c;在生活中常见的例如翻牌计分、翻牌时钟等。 之所以以翻牌的形式是因为其物理设计的原因使其只能滚动翻牌展示数字&#xff0c;在电子显示设备不普及时&#xff0c;使用…

PMBOK® 第六版 估算活动持续时间

目录 读后感—PMBOK第六版 目录 在项目管理中&#xff0c;尤其是在软件开发这样的复杂项目中&#xff0c;工作内容是多种多样的。从需求分析、设计、编码到测试和部署&#xff0c;每个阶段都有其独特的挑战和不确定性。 没有人能独自完成所有估算工作并做到绝对精准。估算涉及…

【Unity Shader】Special Effects(九)Vortex 旋涡(UI)

源码:[点我获取源码] 索引 Vortex 旋涡思路分析旋涡中心旋涡旋转旋涡强度旋涡动画Vortex 旋涡 旋涡效果可以将一张图像以指定点作为旋涡中心,呈顺时针旋涡动画效果,使用动画播放器: 思路分析 首先,旋涡特效的核心也即是旋转(特别是uv坐标的旋转); 在此基础上,旋涡中…

Vue(15)——组合式API②

生命周期函数 选项式组合式beforeCreate/createdsetupbeforeMountonBeforeMount mountedonMounedbeforeUpdateonBeforeUpdateupdatedonUpdatedbeforeUnmountonBeforeUnmountunmountedonUnmounted 父子通信 父传子基本思想&#xff1a; 父组件中给子组件绑定属性…

Vue Devtools -----一条龙安装教程 + 解决安装使用过程的一些问题

一条龙安装教程&#xff08;首次 安装看这里&#xff09; 点击下方网址 进入下载页面 安装 |Vue 开发工具 (vuejs.org)https://devtools-v6.vuejs.org/guide/installation.html 选择适合自己浏览器的版本 以Edge为例&#xff0c;点击下载即可 我以为已经下载过了&#xff0c;…

BUUCTF-MISC-数据包中的线索

下载题目文件&#xff0c;解压发现是一段流量包 使用Wireshark打开 首先过滤HTTP数据流 然后追踪HTTP数据流 通过追踪数据流可以发现 流7 当中有一段base64编码&#xff0c;我们尝试解码 base64基本特征 Base64编码只包含64个字符&#xff1a;大写字母&#xff08;A-Z&#x…

计算机网络笔记002

### 课堂讨论对话 **学生A**: 老师&#xff0c;计算机网络的组成是怎样的&#xff1f;&#x1f914; **老师**: 非常好的问题&#xff01;计算机网络主要由硬件、软件和通信协议三部分组成。我们先从硬件开始讨论吧。 **学生B**: 硬件包括哪些设备呢&#xff1f;&#x1f60…

cmd快速进入文件夹目录下

首先&#xff0c;将文件夹直接点击左键拖动至cmd窗口中&#xff0c;就可以得到目录路径。 还有就是&#xff0c;在命令行直接敲入D:或者C:就可以在磁盘之间进行转换&#xff0c;注意冒号不要丢。 再有&#xff0c;如果进入某磁盘中的一个文件夹&#xff0c;使用cd命令。路径获取…

zabbix email 告警

配置媒介、触发器动作&#xff08;动作、操作&#xff09; 为用户 定义媒体&#xff0c;比如电子邮件地址 动作 - 条件

[图解]静态关系和动态关系

1 00:00:01,060 --> 00:00:04,370 首先我们来看静态关系和动态关系 2 00:00:06,160 --> 00:00:10,040 我们要尽量基于静态关系来建立动态关系 3 00:00:11,740 --> 00:00:13,740 不能够在没有这个的基础上 4 00:00:14,220 --> 00:00:17,370 没有这个的情况下就胡…

2024PHP彩虹工具网源码一个多功能工具箱程序支持72种常用站长和开发等工具

安装&#xff1a; PHP>7.4 伪静态设置Thinkphp 设置/public为网站运行目录 访问你的域名/install进行安装即可 安装扩展 sg11 &#xff0c;fileinfo &#xff0c; ionCube 常用功能 站长工具&#xff1a;ICP备案查询、IP地址查询、域名Whios查询、腾讯域名拦截查询、Mysql…

828华为云征文 | 构建高效搜索解决方案,Elasticsearch Kibana的完美结合

前言 构建高效搜索解决方案&#xff0c;FlexusX服务器与Elasticsearch & Kibana的完美结合&#xff0c;为企业带来云端搜索新体验。FlexusX实例以其卓越性能与灵活扩展性&#xff0c;确保高并发搜索的流畅运行。部署Elasticsearch&#xff0c;享受分布式搜索的精准与快速&a…

从Yargs源码学习中间件的设计

yargs中间件介绍 yargs 是一个用于解析命令行参数的流行库&#xff0c;它能帮助开发者轻松地定义 CLI&#xff08;命令行接口&#xff09;&#xff0c;并提供参数处理、命令组织、help文本自动生成等功能。今天我们来学习一下它对中间件的支持。 中间件的API详细信息&#xff0…

Python | Leetcode Python题解之第430题扁平化多级双向链表

题目&#xff1a; 题解&#xff1a; class Solution:def flatten(self, head: "Node") -> "Node":def dfs(node: "Node") -> "Node":cur node# 记录链表的最后一个节点last Nonewhile cur:nxt cur.next# 如果有子节点&#…

旋转机械故障数据集 全网首发

旋转机械故障 数据集 11G资料 泵、齿轮箱、电机、流量、液压系统、轴承(西储大学、辛辛那提大学、FEMTO、MOSFET)、PHM08挑战数据集、我闪发动机降级模拟数据集、铣床等 旋转机械故障数据集 数据集描述 该数据集是一个综合性的旋转机械故障检测和诊断数据集&#xff0c;旨在…

【ChatGPT】提示词助力广告文案、PPT制作与书籍推荐的高效新模式

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;高效广告推销文案提示词使用方法 &#x1f4af;AI自动生成PPT全流程提示词使用方法 &#x1f4af;精选书籍推荐爆款文案提示词使用方法 &#x1f4af;小结 &#x1f4af;…