将$A$操作看作直接除以2(保留小数),最终再将$a_{i}$取整

记$k$表示$A$操作的次数,$p_{i}$表示第$i$次$A$和第$i+1$次$A$之间$B$操作的次数(特别的,$p_{0}$为第1次$A$操作前,$p_{k}$为最后一次$A$操作后),则有$a'_{i}=\lfloor\frac{a_{i}-\sum_{i=0}^{k}p_{i}2^{i}}{2^{k}}\rfloor$,然后要保证$\sum_{i=0}^{k}p_{i}+k\le K$

考虑$\forall 0\le i<k$,若$p_{i}>1$,可以令$p_{i}-=2$且$p_{i+1}+=1$,则$a'_{i}$的值不改变但操作次数减小,因此可以被其所替代,不妨假设$p_{i}=0或1$

然后考虑$p_{k}$,令$\Delta_{i}=a_{i+1}-a_{i}$,$a_{i}$可以用$(a_{min},\Delta_{i})$来描述,而$p_{k}$不会改变$\Delta_{i}$,因此只需要对于每一组$\Delta_{i}$求出$a_{min}$的范围,即对所有$[\max(a_{min}-(K-k-cnt(C),0),a_{min}]$求并(其中$cnt(C)$表示$C$中1的个数)

换言之,即可得到一个暴力的做法:枚举$k$和$C$,然后对$\Delta_{i}$哈希,对哈希处维护所有区间的并,最后答案即为所有哈希位置上区间长度之和

再考虑$a'_{i}$,由于$C=\sum_{i=0}^{k-1}p_{i}2^{i}<2^{k}$,即可得$a'_{i}=\lfloor\frac{a_{i}-C}{2^{k}}\rfloor=\lfloor \frac{a_{i}}{2^{k}}\rfloor-[a_{i}\ mod\ 2^{k}<C]$

先枚举$k$,然后将$a_{i}$按$a_{i}\ mod\ 2^{k}$排序,对于$C$在相邻两个$a_{i}\ mod\ 2^{k}$区间内部,$\Delta_{i}$和$a_{min}$都是相同的,所不同的仅仅是$cnt(C)$,求出这个区间内$cnt(C)$最小的位置即可

如何求区间$[l,r]$中$cnt(C)$最小的位置,从高到低枚举$l$和$r$的二进制位,若相同必然填相同的数,否则(必然是$l$为0且$r$为1),再分两类讨论:

1.对于之后的位数,若可以做大$cnt(C)=0$(即$l$剩下的部分都为0),必然达到该下限;

2.否则必然有$cnt(C)\ge 1$,同时令$C=100...$可以达到此下限,取这个即可

因此求$cnt(C)$最小的位置,时间复杂度为$o(\log_{2}a_{i})$

$k$枚举范围为$\log_{2}a_{i}$,然后排序为$o(n\log_{2}n)$,再枚举一个区间,求$cnt(C)$最小值为$o(\log_{2}a_{i})$,对$\Delta_{i}$哈希以及区间求并需要$o(n)$,总复杂度即为$o(n^{2}\log_{2}a_{i})$

然后由于复杂度允许,我们还可以避免哈希,而是将所有序列以及对应的区间记录下来,按照序列排序,然后对于一个子区间中所有区间求并即可,时间复杂度为$o(n^{2}\log_{2}a_{i}\log_{2}na_{i})$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 205
4 #define ll long long
5 #define mod 1000000007
6 #define fi first
7 #define se second
8 struct ji{
9 ll l,r,a[N];
10 }o;
11 vector<ji>v;
12 vector<pair<ll,ll> >vv;
13 pair<ll,int>b[N];
14 int n,ans;
15 ll m,a[N],p[N];
16 int check(ll *a,ll *b){
17 for(int i=1;i<n;i++)
18 if (a[i]!=b[i])return (a[i]<b[i])*2-1;
19 return 0;
20 }
21 bool cmp(ji x,ji y){
22 int p=check(x.a,y.a);
23 if (p)return (p==1);
24 return (x.l<y.l)||(x.l==y.l)&&(x.r<y.r);
25 }
26 int min_cnt(ll l,ll r){
27 int s=0;
28 for(int i=59;i>=0;i--){
29 if ((l&(1LL<<i))!=(r&(1LL<<i)))return s+((l&((1LL<<i)-1))>0);
30 s+=((l&(1LL<<i))>0);
31 }
32 return s;
33 }
34 void calc(ll k){
35 if (k<0)return;
36 ll mn=p[1];
37 for(int i=2;i<=n;i++)mn=min(mn,p[i]);
38 if (mn<0)return;
39 o.l=max(mn-k,0LL);
40 o.r=mn;
41 for(int i=1;i<n;i++)o.a[i]=p[i]-p[i+1];
42 v.push_back(o);
43 }
44 int main(){
45 scanf("%d%lld",&n,&m);
46 for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
47 for(int i=0;i<=60;i++){
48 for(int j=1;j<=n;j++)b[j]=make_pair(a[j]%(1LL<<i),j);
49 sort(b+1,b+n+1);
50 for(int j=1;j<=n;j++)p[j]=a[j]/(1LL<<i);
51 calc(m-i-min_cnt(0,b[1].fi));
52 for(int j=1;j<n;j++){
53 p[b[j].se]--;
54 if (b[j].fi<b[j+1].fi)calc(m-i-min_cnt(b[j].fi+1,b[j+1].fi));
55 }
56 p[b[n].se]--;
57 if (b[n].fi<(1LL<<i)-1)calc(m-i-min_cnt(b[n].fi+1,(1LL<<i)-1));
58 }
59 sort(v.begin(),v.end(),cmp);
60 for(int i=0,j=0;i<v.size();i=j){
61 vv.clear();
62 while ((j<v.size())&&(!check(v[i].a,v[j].a))){
63 vv.push_back(make_pair(v[j].l,v[j].r));
64 j++;
65 }
66 sort(vv.begin(),vv.end());
67 ll mx=-1;
68 for(int k=0;k<vv.size();k++){
69 if (mx<vv[k].fi)ans=(ans+vv[k].se-vv[k].fi+1)%mod;
70 else ans=(ans+max(vv[k].se-mx,0LL))%mod;
71 mx=max(mx,vv[k].se);
72 }
73 }
74 printf("%d",ans);
75 }

[atARC086F]Shift and Decrement的更多相关文章

  1. Emmet 使用说明。

    Emmet for Sublime Text Official Emmet plugin for Sublime Text. How to install Available actions Exte ...

  2. 【AtCoder】ARC086

    C - Not so Diverse 题解 选出现次数K多的出来,剩下的都删除即可 代码 #include <bits/stdc++.h> #define fi first #define ...

  3. Xilinx Spartan6常用资源Verilog例化

    // DSP48A1 : In order to incorporate this function into the design, // Verilog : the following insta ...

  4. FPGA分频与倍频的简单总结(涉及自己设计,调用时钟IP核,调用MMCM原语模块)

    原理介绍 1.分频 FPGA设计中时钟分频是重要的基础知识,对于分频通常是利用计数器来实现想要的时钟频率,由此可知分频后的频率周期更大.一般而言实现偶数系数的分频在程序设计上较为容易,而奇数分频则相对 ...

  5. shift粘滞键后门创建/复原批处理

    创建shift粘滞键后门: 1 c: 2 3 cd \Windows\System32\ 4 5 rename sethc.exe bak_sethc.exe 6 7 xcopy cmd.exe se ...

  6. Javascript——arguments的shift问题谈方法“借用”

    今天本来运行了打算这样的方法 arguments.shift() (shift方法是删除数组的第一个元素,例如var arr=[1,2,3,4,5]执行var a=arr.shift();之后,a的值 ...

  7. js中push(),pop(),unshift(),shift()的用法小结

    1.push().pop()和unshift().shift() 这两组同为对数组的操作,并且会改变数组的本身的长度及内容. 不同的是 push().pop() 是从数组的尾部进行增减,unshift ...

  8. eclipse通过ctrl+shift+t无法找到源文件类的解决方法

    通过ctrl + shift + t找对应的类时,类明明存在,并且也在编译路径下,但就是查找不到,一个可能的原因就是eclipse为类建立的索引出了问题. 解决的方法是:找到项目所在工作空间下的.me ...

  9. Javascript的shift()和push(),unshift()和pop()方法简介

    栈方法: Javascript为数组专门提供了push()和pop()方法,以便实现类似栈的行为.来看下面的例子: var colors=new Array();       //创建一个数组 var ...

随机推荐

  1. Dapr + .NET Core实战(十二)服务调用之GRPC

    什么是GRPC gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架. gRPC 的主要优点是: 高性能轻量级 RPC 框架. 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的 ...

  2. 解析csv数据绘制曲线图

    一个解析csv数据的小工具,所做项目中要查看脉冲图谱,经理就让我这个刚入职的小萌新写了个小程序.同事将csv格式的脉冲数据发给我,我的想法就是,将这些csv里的数据作为纵轴,x++为横轴,绘制出折线图 ...

  3. 学习笔记——不带修序列莫队 (luogu2079)小B的询问

    莫队是一种对于询问的离线算法 时间复杂度:O(\(n \sqrt n\)) 大致思想就是 首先将询问离线,然后对原序列分块,使得每一个\(l和r\)都在一个块里 然后按照左节点排序,若所在的块相等,就 ...

  4. PTA数据结构 习题2.1 简单计算器 (20分)

    习题2.1 简单计算器 (20分) 模拟简单运算器的工作.假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算. 输入格式: 输入在一行中给出一个四则运算 ...

  5. python爬虫时,解决编码方式问题的万能钥匙(uicode,utf8,gbk......)

    转载   原文:https://blog.csdn.net/xiongzaiabc/article/details/81008330 无论遇到的网页代码是何种编码方式,都可以用以下方法统一解决 imp ...

  6. Noip模拟33垫底反思 2021.8.8

    T1 Hunter 考场上没写$%p$挂了25分.也是很牛皮,以后打完过了样例一定要检查 因为样例太小了......很容易忘记%%%% 正解随便手模就出来了. 1 #include<bits/s ...

  7. 为什么用于开关电源的开关管一般用MOS管而不是三极管

    区别: 1.MOS管损耗比三极管小,导通后压降理论上为0. 2.MOS管为电压驱动型,只需要给电压即可,意思是即便串入一个100K的电阻,只要电压够,MOS管还是能够导通. 3.MOS管的温度特性要比 ...

  8. STM32中按键中断分析

    在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入 ...

  9. Python | 标识符命名规范

    简单地理解,标识符就是一个名字,就好像我们每个人都有属于自己的名字,它的主要作用就是作为变量.函数.类.模块以及其他对象的名称. Python 中标识符的命名不是随意的,而是要遵守一定的命令规则,比如 ...

  10. Android上安装第三方库

    在Android sdk中安装预安装第三方的(动态,静态)库,到系统中,方便模块无差别的使用. Android.mk include $(CLEAR_VARS) LOCAL_MODULE_TAGS : ...