AtCoder - arc086_d Shift and Decrement分析与实现

AtCoder比赛类型深度对比:ABC/ARC/AGC到底该打哪个? 本文深度解析AtCoder三大赛事ABC、ARC和AGC的核心差异与定位。ABC是新手友好、每周举行的入门赛,题目难度平滑,适合0-1999Rating选手练习速度与基础算法。ARC为中坚选手的试炼场,侧重算法深度与思维挑战,是冲击更高Rating的关键。AGC则为顶尖高手的月度旗舰赛,注重原创性与极限思维。文章结合赛制、难度数据和评分策略,为不同水平选手提供了清晰的参赛选择与进阶路径建议。 阅读详情

分析与思路

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

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

这里有一个关键点:对于每个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;
}

AtCoder ARC181 A题解 AtCoder ARC181题解 阅读详情

相关推荐

AtCoder极简主义:算法竞赛中的认知减负与思维训练

算法竞赛平台AtCoder以极致极简设计著称,其核心并非UI美学,而是通过清除干扰、聚焦问题本质,实现对程序员逻辑建模能力的系统性锤炼。从ABC的确定性翻译、ARC的状态压缩直觉,到AGC的问题本质重构,它构建了一套层层递进的思维训练体系。这种训练直指计算机科学底层——将自然语言精准转化为数学约束,再映射为可执行算法,强调输入输出形式化、边界条件严苛性与时间复杂度敏感性。在工程实践中,该能力直接提升技术面试表现、架构决策质量与问题抽象效率。‘AtCoder ABC’与‘AGC’作为高频搜索热词,正反映出开发

weixin_30843121的博客 234

Atcoder ARC174 A -A Multiply

题意:给你一个长度为N的数组A,再给你一个c,你可以选一个区间l-r,这个区间里的每个数都乘以C(可能是负数) ,求A数组和的最大值。思路:c有可能为负,所以我们可以考虑两种情况,一种是l-r的和最大,另一种是l-r和最小,比较即可AC。本蒟蒻第二篇题解,望多多支持。

qiuyilin2012的博客 815

atcoder:arc129(a,b,c),abc228(a,b,c)题解

arc129 A题: 题意: 输入N,L,R,求L~R这个区间内,有多少个数与N异或运算后小于N?(N^X<N)。 思路: 异或运算:在二进制下,0^0=1,1^1=0,0^1=1,1^0=1. 不难发现,当一个数的最高位1与同位置的1异或后,得到的数一定小于本身。所以只需要反复找N中的1位然后与该位置为1的数异或,结果一定小于本身 ...

archor777的博客 935

AtCoder算法竞技平台简介

AtCoder是日本最大的算法竞技网站,域名为http://atcoder.jp/(注意http://www.atcoder.jp/ 是其官网)。AtCoder支持日语和英语。 AtCoder每周六北京时间20:00(日本标准时间则为21:00)会有比赛。AtCoder的比赛分为三个等级: (1)AtCoder Beginner Contest (ABC),是给算法初学者参加的。总共有4道...

小树学信奥 2万+

Atcoder ARC102测试数据

日本竞赛网站Atcoder的ARC102场的测试数据,题面可以在Atcoder找到。

osg3.6.5---osgEarth3.2 实现数字地球的加载

目前我在网上找得比较多的是osgearth2.10及以下的版本及加载数字地球的方法,但是我使用的是osg3.6.5和osgEarth3.。但是3.x版本和2.x版本差别很大,主要区别在于2.x有7个主要库,而3.x版本只有osgEarth这一个库。所以,特别记录一下。后面我讲他集成到qt的窗体在上传更新新的代码。1.直接上源码pro文件和cpp文件。

枫影竹韵的博客 1009

AtCoder - ARC 117 - C(思维+杨辉三角结论+卢卡斯定理/模拟)

已知一个金字塔的底层颜色分布,蓝白红,上面格子的颜色取决于下面两个相邻格子的颜色。如果相邻格子为同色,那么上面那个格子也是这个颜色;如果相邻格子为不同色,那么上面那个格子就是不同于下面两种颜色的第三种颜色。给你金字塔最顶层的方块数为 N,和底层颜色分布,用字符 B 表示蓝色,字符 W 表示白色,字符R 表示红色。问:金字塔顶端是什么颜色。

m0_64172681的博客 1675

瑞数6.5逆向实战:手把手教你用RPC搞定cookie sign加密(附环境补全技巧)

本文深入解析瑞数6.5逆向实战,重点探讨如何结合环境补全与RPC调用技术来应对其动态加密机制。文章详细介绍了环境指纹采集、双重验证等核心防护原理,并提供了基于Puppeteer的RPC实现方案,手把手教你搞定cookie sign加密,附有实用的环境补全技巧与完整代码示例。

weixin_29315091的博客 1273

【题解】AtCoder ARC128D - Neq Neq

AtCoder ARC128D - Neq Neq 题解

m0_72720401的博客 322

从MySQL到数据仓库:手把手教你用Airflow实现自动化ETL流水线

本文详细介绍了如何利用Airflow构建从MySQL到数据仓库的自动化ETL流水线,涵盖增量抽取策略、PySpark转换优化和数据质量监控等实战细节。特别适合中小规模企业构建高效数据仓库,提升数据处理效率和质量。

rnn9storyteller的博客 828

BOM 数据模型设计

字段名数据类型必填说明物料编码 (Part Number)字符串是唯一标识,主键。建议包含分类前缀(如STD-GEN-CUS-物料名称 (Part Name)字符串是版本 (Revision)字符串是如AB1.0,与编码组合构成唯一实例。状态 (Status)枚举是设计中(Draft)已发布(Released)已归档(Archived)已作废(Obsoleted)类型 (Type)枚举是专用件(Custom)借用件(Borrowed)通用件(Generic)标准件(Standard)

Davina_yu的博客 1756

AtCoder - arc125_a Dial Up

如果a数组中不含有得到b数组所需的数字,那么就直接输出-1,否则就有答案 只有a与第一次不相等 从a数组中找到第一个与最后一个与不相等的数的位置,位置标记为l和r,那么第一次需要移动的次数就是 后续如果发生不匹配的情况移动只需在01之间来回移动,所以每次移动的次数都是1 答案就是每次移动次数加上复制的次数1 int a[N], b[N], n, m; void get_l_r(int cur, int &l, int &r) { for (int i = 1; i &

weixin_52278699的博客 257

Aurix TC387 Ethernet代码解析之二_移植

英飞凌官方仅提供了TC397的例程,故需通过TC397例程来移植到TC387新建工程里。TC397官方例程名称【Ethernet_1_KIT_TC397_TFT】,网络上可以免费获取到,此处不赘述。使用工具【

m0_69929716的博客 884

AT 杂题选做

AtCoder Regular Contest 081 难度正常的一场 ARC。 A 题感觉有点眼熟,但是不管了,反正是可以秒掉的题。 B 题: 难度:2.0 难在第一步的观察(当然可能非常套路) 由于是 2×n2\times n2×n 的网格,所以不难推出,形状一定是多个竖着的骨牌,然后多个横着的骨牌,然后又是竖着的骨牌… 所以就直接排列组合乱搞竖着横着然后从左往右搞就好了。 C 题: 难度:2.9 惨遭这题误导 ...

cryozwq的博客 540

别再只会按按钮了!用NanoStat开源项目学ESP32硬件设计:BOOT与自动下载电路的避坑指南

本文通过NanoStat开源项目深入解析ESP32硬件设计中BOOT与自动下载电路的关键技术。从启动机制、电路设计陷阱到三极管选型,提供了一套完整的避坑指南和优化方案,帮助开发者提升设计可靠性和烧录效率。特别适合中级开发者学习ESP32硬件设计的精髓。

weixin_30296405的博客 439

最新Python爬虫实战(入门爬虫篇)——案例7:电影网站电影数据采集(详细爬虫思路截图+抓包动图演示+完整爬虫代码+详细注释)

本次案例通过Python爬虫技术,成功实现了对某电影网站Top250多页电影详细信息的批量爬取与Excel保存。代码采用模块化设计,包含分页请求构造、XPath+正则提取结构化信息、Excel数据持久化保存等完整流程。通过配置User-Agent等请求头信息,有效模拟浏览器行为以绕过豆瓣基础反爬策略。整个爬虫逻辑遵循"分页遍历 → 请求页面 → 解析HTML → 提取电影信息 → 保存到Excel"的标准流程,与主流静态网站爬取范式高度一致。

努力让自己发光,对的人才能迎着光而来 11万+

AtCoder arc146. B - Plus and AND题解

AtCoder arc146. B - Plus and AND题解

post12345的博客 403

C#上位机实战:Modbus RTU串口通信(CRC校验+超时重发完整实现)

在工业自动化上位机开发中,Modbus RTU是串口通信的事实标准协议,SerialPort是 .NET 平台操作串口的原生类,无需依赖第三方库即可实现基础通信。实际项目中,工控现场存在电磁干扰、串口丢包、设备响应延迟等问题,CRC 数据校验用于保证报文完整性,超时重发机制用于提升通信稳定性。本文从零封装一套可直接落地的 Modbus RTU 通信组件,包含完整的校验算法、超时控制、重发逻辑,并配套 WinForm 演示界面。本文基于 C# 原生SerialPort类,实现了一套生产可用。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 389

[ARC086]F - Shift and Decrement 位运算+数论+DP

题面 可以证明,在最后一次÷2÷2操作之前,不必要进行连续的两次−1-1操作。因为连续的−1-1操作可以通过先÷2÷2来减少操作次数。 我们定义popcount(x)popcount(x)来表示xx二进制表示中11的个数,那么假设做了kk次÷2÷2操作(可以发现kk不会超过6060),那么可以把所有操作等价为: 1. −p-p (p2k)(p,耗费popcount(p)popcount(p

DOFYPXY的博客 776

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Atcoder arc102F

完全不会的神仙结论题。 我们称一次操作iii是将pi−1,pi,pi+1p_{i-1},p_i,p_{i+1}pi−1​,pi​,pi+1​翻转(pi−1>pi>pi+1p_{i-1}>p_i>p_{i+1}pi−1​>pi​>pi+1​)。 首先可以发现一个性质,如果我们做了操作iii,那么永远不可能再做操作i−1i-1i−1或i+1i+1i+1了。考虑反证,...

mayaohua 428

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Atcoder arc092

E-Both Sides Merger 给你一个序列,支持两种操作,直到序列中只有一个数时停下来,使得剩下数最大,并输出选数方案。 操作1:扔掉一个最前端或最后端的元素。操作2:选取一个不在边界上的元素,取其相邻两个数的和替换它,并删去它相邻的两个数。 n<=1000,|ai|<=1e9。 结论1:最后留下的数是原序列若干个数的和,并且这些数的下标同奇偶。 证明:一...

b121382291的博客 313

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Atcoder arc 084 C - Snuke Festival(前缀和+二分)

题目链接:http://arc084.contest.atcoder.jp/tasks/arc084_a C - Snuke Festival Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement The season for Snuke Festival

far away 997

Atcoder ARC 077 E - guruguru 差分

题意: 你有一个遥控器用来控制电视亮度m,遥控器上有两个按键,现在要确定一个“喜欢”亮度,使得操作次数最少。 按键: 每次把亮度+1,当亮度等于m时,按下按键亮度会变成1。 按下按键会直接将亮度调整的你最初设定的“喜欢”亮度。 数据范围: 2≤n,m≤1052≤n,m≤10^5 1≤ai≤m1≤ai≤m ai≠ai+1ai≠ai+1 算法: 开一

Cherries 1186

【AtCoder】【ARC080F】Prime Flip

Description 有无限多的硬币排成一排,其中有一些位置的的硬币是反面的,其他的都是正面的, 现在你每次可以翻转一个区间的所有硬币,要求区间的长度必须为奇质数, 求最少操作次数, Solution 先把原序列差分,每次就只会更改两个点, 分以下的几种情况讨论: 1. 区间长度为奇质数,代价为1; 2. 区间长度为偶数,代价为2(2:5-3, 4:7-3,大于6的用哥德巴赫...

546

【AtCoder】ARC094(C-F)题解

C - Same Integers 题解 要么三个都达到最大的数,要么三个都到达最大的数+1,判断是前一种情况的方法是不断垫高前两大的,看之后最小的那个和最大的那个差值是不是2的倍数 否则就是第二种情况 代码 #include <iostream> #include <cstdio> #include <cstring> #include <al...

weixin_30872867的博客 371

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 232
上一篇: AtCoder - abc138_f Coincidence
下一篇: Lazy Narek CodeForces - 2005C分析与解答
里欧布鲁斯
博客等级 码龄4年 173粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值