AtCoder - arc086_d Shift and Decrement分析与实现

news2025/3/25 22:15:32

分析与思路

可以把操作流程表示成下图

以进行四次除法操作为例:

这里有一个关键点:对于每个p_i (0<= i <=x-1) ,x是除法操作的次数,如果p_i>=2,可以将2个p_i的减法操作去掉,在p_(i+1)中增加一个减法操作,这样可以用更少的减法操作次数达到同样的效果,所以最终,每个p_i (0<= i <=x-1),p_i要么是0,要么是1,p_x中保存了自底向上累计的减法,所以p_x取值任意

还可以继续简化操作,p_i (0<=i<=x-1)如果是1的话,可以将其去除,并让p_0增加2的 i 次方,此时虽然简化了操作,但是会增加操作次数

如果现在把操作次数统计为p_0+x+p_x,这样会用更多的次数完成相同的操作,这里有一个关键点,根据上面的p_0被累加的方式,p_0的二进制表达中1的个数是真实的p_0到p_(x-1)的操作次数的和,例如p_0 = 11011010,这代表着在p_0被增加前,p_0=0 p_1=1 p_2=0 p_3=1等等

这样,操作被简化为:

第一步:先进行p_0次减法操作,这里令y=p_0

第二步:再进行x次除法操作,

第三步:最后再进行p_x次减法操作,这里令z=p_x

操作次数为:y的二进制表达中1的出现次数+x+z

然后这里有一个关键观察,y的值不会超过2^x,就算y的二进制表达每一位都是1,也比2^x小1,于是可以将a_i表示成 a_i = b_i * 2^x + c_i,其中 0<=c_i<2^x,因为这样表示之后,

如果c_i>=y 则 经过前两步的操作,a_i变成b_i

如果c_i<y,则经过前两步的操作 a_i变成b_i - 1

将所有的c_i排序,去重,则当y处于以下的某一区间时,得到的前两步操作后的结果序列是相同的

[0,c1]

[c1+1,c2]

[c2+1,c3]

... ...

[c_(t-1) + 1, c_t] 其中 t 是c_i排序去重后的数的个数

当p处于某一区间时,为让所需操作次数减少,应该让p的二进制表达中1的个数尽量少(求一个区间[a,b]中的数的二进制表达中1的数目最少的数的方法见后)

现在,思路可以是,枚举x,因为指数爆炸,x的范围是[0,60],然后枚举y,具体方式是对每个区间求二进制表达中1的个数最少的数就是这个区间的y,然后计算经过前两步操作后得到的数的序列,同时也根据k和前两步操作的次数,计算出第三步操作可以实施的次数,第三步操作其实是在整体移动这个数列
 

这里有一个关键点,用一个数组可以描述一个数列(长度为n)的形状,这个数组中的每个元素依次是:
a[1]-a[1] a[2]-a[1] a[3]-a[1] ... a[n]-a[1]

当数列的形状相同时,只要看a[1]有多少个不同的取值,就知道这个数列有多少不同的取值情况

记录每个数列的形状下,a[1]有多少个不同取值就可以

我们的算法在枚举前两步后,可以得到第三步的一个操作数量范围,这对应着某个形状下,一个a[1]的取值范围,a[1]的取值范围们的并集就是能取到的a[1]的值,这个并集中元素的数量就是这种形状下不同序列的数量

求区间[a,b]中二进制表达中1的数目最小的数的方法

设一个数p的二进制表达中1的数目为popcount(p) 

求(a , b]中的答案可以用这样的方法,从高位到低位一位一位对比a和b,如果该位相同,则结果的该位和该位上的值相同,如果该位不同,则说明a的该位上是0,b的该位上是1,那么让结果的该位为1,后面的所有位置置0就可以

将[a,b]转化为(a-1,b]使用上述算法即可,但是有一个特殊情况,如果[a,b]中a是0,那么不能用上面的方法,应该直接返回结果0

合并区间的方法

记每个区间[l,r]

将区间按照左端点大小进行排序,记录当前已经处理到的位置的下一个位置为L,

分类讨论:如果一个区间的右端点小于L,那么不处理这个区间,否则,如果这个区间的左端点小于等于L,则区间带来的贡献是r-L+1,之后L=r+1,如果这个区间的左端点大于L,则区间带来的贡献是r-l+1,之后L=r+1

实现中的注意点

如果1<<60,会导致溢出,要写成1LL<<60

可以用map<vector<ll>,ll> 来表示某一种形状的序号,用tot表示当前形状的总数,如果当前形状的序号是0,那么当前形状的序号被编为tot+1

复杂度分析略

#include<bits/stdc++.h>
using namespace std;

#define ll long long


const ll maxn=200+5,mod=1000000007;
ll power[maxn],a[maxn],b[maxn],c[maxn],fnal[maxn],c1[maxn];
ll k,n,tot;

map<vector<ll>,ll> mp;

vector<pair<ll,ll>> range[maxn*100];

ll find_minpopcount(ll x,ll y){
    if(x==-1) return 0;

    ll ans=0;
    for(ll i=60;i>=0;i--){
        if((x&(1LL<<i))==0 && (y&(1LL<<i))){
            ans+=(1LL<<i);
            break;
        }
        if(x&(1LL<<i)) ans+=(1LL<<i);
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);

    //预处理2的x次方
    power[0]=1;
    for(ll i=1;i<=60;i++) power[i]=power[i-1]*2;
    //cout<<power[59]<<"\n";
    //cout<<power[60]<<"\n";
    //cout<<find_minpopcount(4,6)<<"\n";

    cin>>n>>k;
    for(ll i=1;i<=n;i++) cin>>a[i];

    for(ll x=0;x<=60;x++){
        for(ll i=1;i<=n;i++){
            b[i]=a[i]/power[x];
            c[i]=a[i]%power[x];
            c1[i]=c[i];
        }
        stable_sort(c1+1,c1+1+n);
        ll t=unique(c1+1,c1+1+n)-(c1+1);
        c1[0]=-1;
        for(ll i=1;i<=t;i++){
            ll y=find_minpopcount(c1[i-1],c1[i]);
            ll cnt=__builtin_popcountll(y);
            ll flag=1;
            for(ll j=1;j<=n;j++){
                fnal[j]=b[j];
                if(c[j]<y) fnal[j]--;
                if(fnal[j]<0) {
                    flag=0;break;
                }
            }
            if(flag==0) continue;
            ll z=k-x-cnt;
            if(z<0) {
                continue;
            }
            /*
            cout<<"发现合法结果:"<<"\n";
            printf("x=%d cnt=%d\n",x,cnt);
            for(ll i=1;i<=n;i++) cout<<fnal[i]<<" ";
            cout<<"\n";
            */
            ll minfnal=*min_element(fnal+1,fnal+1+n);
            ll max_decrease_times=min(minfnal,z);
            pair<ll,ll> p={max(fnal[1]-max_decrease_times,0LL),fnal[1]};
            //求差分模式
            vector<ll> vec;
            for(ll j=1;j<=n;j++){
                vec.push_back(fnal[j]-fnal[1]);
            }
            if(mp[vec]==0) {
                mp[vec]=++tot;
            }
            range[mp[vec]].push_back(p);
        }
    }

    ll ans=0;
    for(ll i=1;i<=tot;i++){
        //printf("第%lld种差分模式:\n",i);
        stable_sort(range[i].begin(),range[i].end());
        ll L=0;
        for(ll j=0;j<range[i].size();j++){
            pair<ll,ll> tmp=range[i][j];
            ll l=tmp.first,r=tmp.second;
            //printf("区间:[%lld , %lld]\n",l,r);
            if(r<L) continue;
            if(l<=L) ans=(ans+(r-L+1))%mod;
            else ans=(ans+(r-l+1))%mod;
            L=r+1;
        }
    }
    cout<<(ans+mod)%mod<<"\n";
    return 0;
}

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

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

相关文章

tcping 命令的使用,ping IP 和端口

1. ‌Windows系统安装‌ ‌下载tcping工具‌&#xff1a;根据系统位数&#xff08;32位或64位&#xff09;下载对应的tcping.exe文件。‌安装步骤‌&#xff1a; 将下载的tcping.exe文件复制到C:\Windows\System32目录下。如果下载的是64位版本&#xff0c;需将文件名改为tcpi…

天地图InfoWindow插入React自定义组件

截至2025年03月21日天地图的Marker不支持添加Label; 同时Label和Icon是不支持自定义HTMLElement只支持String&#xff1b;目前只有InfoWindow支持自定义HTMLElement; 效果图 React核心api import ReactDOM from react-dom/client const content document.createElement(div);…

003-掌控命令行-CLI11-C++开源库108杰

首选的现代C风格命令行参数解析器! &#xff08;本课程包含两段教学视频。&#xff09; 以文件对象监控程序为实例&#xff0c;五分钟实现从命令行读入多个监控目标路径&#xff1b;区分两大时机&#xff0c;学习 CLI11 构建与解析参数两大场景下的异常处理&#xff1b;区分三…

鸿蒙HarmonyOS NEXT应用崩溃分析及修复

鸿蒙HarmonyOS NEXT应用崩溃分析及修复 如何保证应用的健壮性&#xff0c;其中一个指标就是看崩溃率&#xff0c;如何降低崩溃率&#xff0c;就需要知道存在哪些崩溃&#xff0c;然后对症下药&#xff0c;解决崩溃。那么鸿蒙应用中存在哪些崩溃类型呢&#xff1f;又改如何解决…

机器学习——分类、回归、聚类、LASSO回归、Ridge回归(自用)

纠正自己的误区&#xff1a;机器学习是一个大范围&#xff0c;并不是一个小的方向&#xff0c;比如&#xff1a;线性回归预测、卷积神经网络和强化学都是机器学习算法在不同场景的应用。 机器学习最为关键的是要有数据&#xff0c;也就是数据集 名词解释&#xff1a;数据集中的…

【canvas】一键自动布局:如何让流程图节点自动找到最佳位置

一键自动布局&#xff1a;如何让流程图节点自动找到最佳位置 引言 在流程图、拓扑图和系统架构图设计中&#xff0c;节点布局往往是最令人头疼的问题。如果手动调整每个节点位置&#xff0c;不仅耗时费力&#xff0c;还难以保证美观性和一致性。本文将深入解析如何实现自动布…

[每周一更]-(第137期):Go + Gin 实战:Docker Compose + Apache 反向代理全流程

文章目录 **1. Go 代码示例&#xff08;main.go&#xff09;****2. Dockerfile 多段构建**3.构建 Docker 镜像**4. docker-compose.yml 直接拉取镜像****5. 运行容器****6. 测试 API**7、配置域名访问**DNS解析&#xff1a;将域名转换为IP地址****DNS寻址示例** 8.错误记录 访问…

SpringCache小记

Spring Cache 小记 官方文档&#xff1a;https://springdoc.cn/spring-cache-tutorial/ 基础知识 常用注解 EnableCaching&#xff1a;开启缓存功能&#xff0c;一般放在启动类上。 Cacheable&#xff1a;表示该方法支持缓存。当调用被注解的方法时&#xff0c;如果对应的键已…

Web-Machine-N7靶机通关攻略

获取靶机ip arp-scan -l 端口扫描 nmap xxxx 访问80端口发现没用 扫描目录 gobuster dir -u http:/192.168.117.160 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium,txt -x php,html,txt ,zip 打开exploit.html 点击F12&#xff0c;修改localhost为靶机ip&#…

第十五次CCF-CSP认证(含C++源码)

第十五次CCF-CSP认证 小明上学满分思路 数据中心满分思路 小明放学满分题解 小明上学 题目链接 满分思路 其实题目看着长&#xff0c;但是做起来是非常好写的&#xff0c;其实主要原因在于&#xff0c;他的红绿灯的变化规律是一定的&#xff0c;而且小明路上的每次红绿灯情况…

Java-servlet(七)详细讲解Servlet注解

Java-servlet&#xff08;七&#xff09;详细讲解Servlet注解 前言一、注解的基本概念二、Override 注解2.1 作用与优势2.2 示例代码 三、Target 注解3.1 定义与用途3.2 示例代码 四、WebServlet 注解4.1 作用4.2 示例代码 五、反射与注解5.1 反射的概念5.2 注解与反射的结合使…

SQLark 实战 | 如何通过对象名和 DDL 快速搜索数据库对象

在数据库运维管理、应用开发和问题定位时&#xff0c;常常需要搜索相关的数据库对象。本文将为你介绍如何使用 SQLark 的搜索功能&#xff0c;实现对数据库对象的快速查找与定位。 &#x1f449; 前往 SQLark 官网&#xff1a;www.sqlark.com 下载全功能免费版。 通过对象名称搜…

C/S模型-TCP

下图是基于TCP协议的客户端/服务器程序的一般流程&#xff1a; TCP协议通讯流程 服务器调用socket()、bind()、listen()完成初始化后&#xff0c;调用accept()阻塞等待&#xff0c;处于监听端口的状态&#xff0c;客户端调用socket()初始化后&#xff0c;调用connect()发出SY…

51c自动驾驶~合集24

我自己的原文哦~ https://blog.51cto.com/whaosoft/11926510 #DriveArena 上海AI Lab又放大招&#xff1a;首个高保真闭环生成仿真平台 仓库链接&#xff1a;https://github.com/PJLab-ADG/DriveArena 项目链接&#xff1a;https://pjlab-adg.github.io/DriveArena/ D…

19.哈希表的实现

1.哈希的概念 哈希(hash)⼜称散列&#xff0c;是⼀种组织数据的⽅式。从译名来看&#xff0c;有散乱排列的意思。本质就是通过哈希函数把关键字Key跟存储位置建⽴⼀个映射关系&#xff0c;查找时通过这个哈希函数计算出Key存储的位置&#xff0c;进⾏快速查找。 1.2.直接定址法…

【PCB工艺】晶体管的发展历史

晶体管被认为是20世纪最伟大的发明之一&#xff0c;因为没有晶体管就不会有现代电脑、手机或平板​​&#xff0c;你也无法阅读到这里的内容&#xff0c;因为不存在网络。 ——本文纯粹出于对过往奋斗在这个领域中科学家的缅怀。科学家有太多宝贵的思想和经验值得我们认真总结和…

通向AGI的未来之路!首篇2D/视频/3D/4D统一生成框架全景综述(港科大中山等)

文章链接&#xff1a; https://arxiv.org/pdf/2503.04641 摘要 理解并复现现实世界是人工通用智能&#xff08;AGI&#xff09;研究中的一个关键挑战。为实现这一目标&#xff0c;许多现有方法&#xff08;例如世界模型&#xff09;旨在捕捉支配物理世界的基本原理&#xff0…

【亚马逊云科技】大模型选型实战(挑选和测评对比最适合业务的大模型)

文章目录 前言1、实验内容2、手册内容 一、环境准备二、Prompt 实战与模型配置2.1 基于 Amazon Bedrock 对比测试不同模型的逻辑推理效果2.2 基于 Amazon Bedrock 对比测试不同模型知识问答能力2.3 Prompt 实战结果分析 三、基于 Amazon Bedrock Evaluations 进行模型评测与自动…

调用feapder作为子程序时setting.py文件不起作用

feaper 官方文档地址&#xff1a; 简介及安装 - feapder官方文档|feapder-document 问题&#xff1a; 在最近的开发中需要调用feapder作为主程序调用的子程序时发现自动入库时无法入库&#xff0c;通过查看日志信息发现连接数据库时被拒绝连接了&#xff0c;但是我的setting.p…

【从零开始学习计算机科学】软件测试(九)Web系统测试 与 数据库测试

【从零开始学习计算机科学】软件测试(九)Web系统测试 与 数据库测试 Web系统测试Web系统基本组成Web系统的服务器端应用特点Web系统测试的分类Web应用系统测试的实施功能测试链接测试表单测试性能测试连接速度测试负载测试压力测试可用性测试导航测试图形测试内容测试表格测试…