Pinely Round 2 (Div. 1 + Div. 2) F. Divide, XOR, and Conquer(区间dp)

这篇具有很好参考价值的文章主要介绍了Pinely Round 2 (Div. 1 + Div. 2) F. Divide, XOR, and Conquer(区间dp)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目

给定长为n(n<=1e4)的数组,第i个数为ai(0<=ai<2的60次方)

初始时,区间为[1,n],也即l=1,r=n,

你可以在[l,r)中指定一个k,将区间分成左半边[l,k]、右半边[k+1,r]

1. 如果左半边异或和与异或和的异或和相等,则可以二选一,要么保留左半边,要么保留右半边

2. 否则,只能保留异或和大的那半边

当l=r时,游戏结束

对于每个i,判断是否能通过适当操作,使得游戏结束时l=r=i

实际t(t<=1e4)组样例,保证sumn不超过1e4

思路来源

力扣群 潼神

Pinely Round 2 (Div. 1 + Div. 2) F. Divide, XOR, and Conquer(区间dp),# 区间dp,区间dp,异或

题解

这个st0[i]和ed0[i]实际只需要占一位,分开写的话可读性会好一点

此处由于值域限制,直接维护在了st[i]和ed[i]的第60位

n=1e4,说明只能是O(1)转移的区间dp

异或和的两种情况:

1. [l,r]异或和为0,那么[l,x](x<r)和[y,r](y>l)的区间都可以异或出

2. [l,r]异或和为s(s≠0),记s的最高位为b,

那么,如果[l,x](x<r)的异或和包含b这一位,[l,x]的异或和就一定大于[x+1,r]的异或和

同理,如果[y,r](y>l)的异或和包含b这一位,[y,r]的异或和就一定大于[l,y-1]的异或和

判断

①左端点/右端点第60位打过标记,说明存在共左端点/右端点的更大的区间异或和为0

②[l,r]异或和为s,s和左端点/右端点的标记有交,说明存在共左端点/右端点的更大的区间的异或和的最高位能被s取到,也就是s比区间另一半大

设位

①如果异或和为0,在第60位打标记

②否则,在异或和最高位打标记

心得

本题是长区间向短区间下放,没怎么写过,但本身区间dp也很灵活

由于下放时一定需要固定一个端点,所以可以将信息维护在端点处供后续使用

也就只需要开一维,不像传统区间dp开两位数组那样了

__builtin_clzll(s)是获取64位数二进制前导0个数

63-__builtin_clzll(s)是获取64位数二进制最高位的1是第几位

从右往左,从第0位开始数,也就是1<<b中的b,不存在时为-1

32位数时,可以对应改成__builtin_clz(s)、31-__builtin_clz(s)文章来源地址https://www.toymoban.com/news/detail-698859.html

代码

#include<bits/stdc++.h>
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<ll,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__)
typedef unsigned ui;
//typedef __uint128_t L;
typedef unsigned long long L;
typedef unsigned long long ull;
const int N=1e4+10,B=60;//xor=0代表的位
int t,n;
ll v,bl[N],br[N],sum[N];
char ans[N];
bool cal(int l,int r){
	if(l==1 && r==n)return 1;
	//之前的[l,R](R>r)的异或和有0
	//之前的[L,r](L<l)的异或和有0
	if(bl[l]>>B&1 || br[r]>>B&1)return 1;
	ll s=sum[r]^sum[l-1];
	return (s&bl[l]) || (s&br[r]);
	//[l,r]的异或和有[l,R](R>r)的异或和的最高位
	//[l,r]的异或和有[L,r](L<l)的异或和的最高位
}
void op(int l,int r){
	ll s=sum[r]^sum[l-1];
	int b;
	if(!s)b=B;	// 当前[l,r]的异或和有0 
	else b=63-__builtin_clzll(s); // 当前[l,r]的异或和的最高位
	bl[l]|=1ll<<b;
	br[r]|=1ll<<b;
}
int main(){
	sci(t);
	while(t--){
		sci(n);
		rep(i,1,n){
			scanf("%lld",&v);
			sum[i]=sum[i-1]^v;
			bl[i]=br[i]=0;
			ans[i]='0';
		}
		per(sz,n,1){
			rep(l,1,n+1-sz){
				int r=l+sz-1;
				//printf("l:%d r:%d ok:%1d s:%lld b:%d\n",l,r,cal(l,r),sum[r]^sum[l-1],63-__builtin_clzll(sum[r]^sum[l-1]));
				if(cal(l,r)){
					op(l,r);
					if(l==r)ans[l]='1';
				}
			}
		}
		ans[n+1]='\0';
		printf("%s\n",ans+1);
	}
	return 0;
}

到了这里,关于Pinely Round 2 (Div. 1 + Div. 2) F. Divide, XOR, and Conquer(区间dp)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 云服务器SVN仓库搭建(以阿里云为例)

    远程连接阿里云服务器 安装svn(注意需要root权限使用命令sudo su) yum install subversion 安装成功后查看svn版本 svnserve --version  创建版本库的根目录 mkdir /var/svn 创建代码仓库 svnadmin create /var/svn/test    当前生成的目录结构 此处为svn的配置文件 创建用户名和密码 编辑passwd文件 创建

    2024年02月14日
    浏览(41)
  • 计算机网络——计算机网络体系结构

    1.1 概念 一般认为,计算机网络是一个将分散的,具有独立功能的计算机系统,通过通信设备与线路连接起来,由功能完善的软件实现资源共享的信息传递的系统,简而言之,计算机网络就是一些 互联的,自治的计算机系统的集合 1.2 组成 (1)从组成部分:由 硬件,软件,

    2024年02月15日
    浏览(52)
  • appium解决报错:ModuleNotFoundError: No modulenamed ‘selenium.webdriver.common.options‘

    出现这个错误是因为selenium与Appium-Python-Client版本不匹配。 appium: selenium: selenium要4.0版本以上 卸载selenium3.141: 如果安装selenium4.0 ** 会提示如果安装了,appium-python-client 2.7.1,那就要安装selenium~=4.1,这样依赖才匹配。selenium3.141和selenium4.0,4.1相差不是很大,但是selenium不同版本里

    2024年02月11日
    浏览(41)
  • SpringBoot+Prometheus+Grafana 监控面板(项目配置方式【入侵】)

    提示:本文使用SpringBoot 简单样例,介绍基础配置和使用方法 包含内容:Docker、SpringBoot、Maven、 Prometheus、Grafana等 提示:本文包含官网内容介绍,具体更项目的学习,请参照各官网文档,谢谢 官网:https://prometheus.io/ 文档地址:https://prometheus.io/docs/introduction/overview/ 使用领先

    2024年02月16日
    浏览(51)
  • 《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码

    在注意力机制中,每个查询都会关注所有的键-值对并生成一个注意力输出。由于查询、键和值来自同一组输入,因此被称为 自注意力(self-attention),也被称为内部注意力(intra-attention)。本节将使用自注意力进行序列编码,以及使用序列的顺序作为补充信息。 给定一个由

    2024年02月06日
    浏览(44)
  • ubuntu22.04编译安装使用gstreamer指南

    ubuntu发行版22.04,该发行版内置Gstreamer1.20.1,gstreamer源码最新版本为1.20.3,差距不大 下载gstreamer源码 安装git 下载gstreamer 安装meson gstreamer1.60以后(不包含1.60),使用meson+ninja来构建 安装glib gstreamer是基于glib-gobject来实现的 安装libsoup 安装libunwind 安装libdw 安装g-ir-scanner 系统中

    2024年02月05日
    浏览(74)
  • 【Python 中的 plt.hist 函数详解】

    plt.hist 函数用于绘制直方图。直方图是一种用来表示数据分布的图形,它将数据分成若干个区间,然后统计每个区间中数据的数量,最终以柱状图的形式展示出来。 直方图主要用于可视化数据的分布情况。它将数据划分为一系列的区间(也称为箱子或柱子),然后计算每个区

    2024年04月13日
    浏览(44)
  • FDTD算法及其应用

    一、电磁场问题数值计算方法         有许多的数值计算方法用于解决电磁场问题。其中,一些最常用的方法包括:         1.有限元法(Finite Element Method,FEM):这种方法将连续的求解域离散化为有限个小的单元,对每个单元进行数值求解,然后将所有单元的解组

    2024年01月25日
    浏览(35)
  • idea2021配置Git&GitHub&账号登录授权

    下载地址:https://git-scm.com/downloads 安装很简单,这里不多废话。 点击 GitManage Remotes…点\\\"+\\\"号添加别名和仓库地址 转圈圈的同时会弹出浏览器,打开授权界面、 点击授权按钮后,输入账号密码登录,并再次点击授权按钮 最终出现下面提示,则over! over之后再去idea看,发现已

    2023年04月08日
    浏览(43)
  • 【0002】JDK1.7安装和环境变量配置(Windows7操作系统)

    链接:https://pan.baidu.com/s/1ZJTlD-bRw9VCNA5qY-ZU-A  提取码:3d4h 在Windows7操作系统下安装JDK1.7及配置环境变量。其它版本的JDK及操作系统安装步骤,基本上没有太大的差异,所以此文也可以指导安装其它系统中的不同版本的JDK。 先安装JDK再配置环境变量 JDK版本:JDK-7u80-windows-x64版本

    2024年03月25日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包