将$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. 微信小程序 开发 “婚礼邀请函”

    成品展示: 5个页面 我们来讲解哈(上面地图位置随便定的点) 1.首页开发 一开始进来显示首页  然后默认开始播放背景音乐,这个背景音乐点击右上角图标可以暂停(有动画),然后点击新郎和新娘文字可以调到 ...

  2. 生成base64图片验证码

    github.com/mojocn/base64Captcha func GetCaptcha(c *gin.Context){ driver := base64Captcha.NewDriverDi ...

  3. Windows Terminal 美化教程

    Windows Terminal 美化教程 1.安装Windows Terminal 在微软商店搜索Windows Terminal下载即可 2.安装相应的插件 使用管理员权限打开Windows Te ...

  4. Conda 命令

    Conda 命令 1 检验当前conda的版本 conda -V 2 conda常用的命令 查看已有的虚拟环境 conda env list 创建虚拟环境和删除虚拟环境 anaconda命令创建pyt ...

  5. 洛谷4366——最短路(dijkstra,思维,异或)

    题目大意 给定一个n个点,m条边的图,每条边有边权,而每个点\(i\)也可以直接到达\(j\),代价是\(i\ xor\ j\),给定一个S和T,求S到T的最小代价 其中\(n\le100000,m\ ...

  6. Java中的基本类型和包装类

    Java中基本数据类型与包装类型有   基本类型     包装器类型   boolean Boolean char Character int Integer byte Byte short Shor ...

  7. 【错误分析】NX error status: 32

    在进行NX 制图里面的表格注释合并单元格时,总是报错NX error status: 32,找了很久都不知道问题所在. 报错提示如下: NXOpen.NXException: NX error sta ...

  8. python flask1

    以这个服务端代码为例,简单了解一下flask的运用. 1.app = Flask(__name__)记住就好了 2.@app.route("/")记住就好了:注意括号里的是调用这个 ...

  9. 【UE4 设计模式】单例模式 Singleton Pattern

    概述 描述 保证一个类只有一个实例 提供一个访问该实例的全局节点,可以视为一个全局变量 仅在首次请求单例对象时对其进行初始化. 套路 将默认构造函数设为私有, 防止其他对象使用单例类的 new运算符. ...

  10. P2120 [ZJOI2007]仓库建设

    P2120 [ZJOI2007]仓库建设 怎么说呢?算是很水的题了吧... 只要不要一开始就把dp想错就行... #include<bits/stdc++.h> #define ll lo ...