令$a_{i}$和$b_{i}$分别为$A_{i}$和$B_{i}$减少的值,考虑判定$\{a_{i}\},\{b_{i}\}$能否被得到

结论:$\{a_{i}\},\{b_{i}\}$能否被得到当且仅当满足以下条件——

1.$0\le a_{i}\le A_{i}$,$0\le b_{i}\le B_{i}$

2.$a_{i}+b_{i-1}+b_{i}$为偶数(其中$b_{0}=b_{n}=0$)

3.$a_{i},b_{i-1},b_{i}$这三个数中不存在一个数大于另外两数之和

必要性——第1个条件由非负的限制显然,第2个和第3个条件均考虑$a_{i},b_{i-1},b_{i}$这三个数中,每一次对其中一个数+1,另外两数中必然恰有一个数+1,显然具有上述性质

充分性——归纳,并考虑最后一次操作,取第一个$a_{i}>0$的位置和其之后第一个$a_{j}=b_{j-1}+b_{j}$的位置即可(具体存在性和正确性可以自行分析)

对于$A_{i}+B_{i-1}<B_{i}$,注意到$0\le b_{i}\le B_{i}$即为第3个条件的必要条件,可以忽略此条件,因此不妨调整为$B_{i}=A_{i}+B_{i-1}$(类似地,也可以对$B_{i-1}$做此操作)

重复此过程(可以用类似dijkstra的贪心来做),即有$|B_{i}-B_{i-1}|\le A_{i}$

此时,对于$A_{k}\ge B_{k-1}+B_{k}$(其中$2\le k\le n-1$),同样可以忽略$0\le a_{k}\le A_{k}$的条件,因此操作$(i,j)$(其中$i<k<j$)不妨改为操作$(i,k)$和$(k,j)$,这样只让$A_{k}$额外减小2(仍合法)且操作数增加

换言之,不存在这样的操作,即不妨变为$[1,k]$和$[k,n]$这两个子问题

重复此过程,考虑最终的子问题,即有$\forall 2\le i\le n-1,|B_{i}-B_{i-1}|\le A_{i}<B_{i-1}+B_{i}$,且类似前面的,不妨再令$A_{1}=B_{1},A_{n}=B_{n-1}$

(注意这个过程的实现并不需要递归,直接从前往后枚举并划分即可)

另一方面,注意到操作次数即为$\frac{\sum_{i=1}^{n}a_{i}}{2}$,同时$\{a_{i}\}$与最终的$\{A_{i}\}$一一对应,因此从$\{a_{i}\}$的角度来看,问题即求有多少组$\{a_{i}\}$满足$\frac{\sum_{i=1}^{n}a_{i}}{2}$取到最大值且$\exists \{b_{i}\}$满足结论中的条件

考虑从前往后依次填$b_{i}$,并要求$\forall 1\le j<i,a_{j}=A_{j}$,求出此时$b_{i}$可行的范围

若已经确定$b_{i-1}$,则$b_{i}$的范围为$\{x\mid x\in [\abs{A_{i}-b_{i-1}},\min(A_{i}+b_{i-1},B_{i})]$且$x\equiv a_{i}+b_{i-1}(mod\ 2)\}$,那么即要将$b_{i-1}$的范围内所有值代入并求并

归纳最终的形式为$\{x\mid x\in [L,B_{i}]$且$x\equiv p(mod\ 2)\}$且该集合非空(也即必然包含$B_{i}-1$或$B_{i}$),转移可以自行分类讨论得到(式子较为复杂),进而不难证明归纳

以此法构造,即$a_{1},a_{2},...,a_{n-1}$都可以取到$A_{i}$,且$a_{n}$可以取到$A_{n}-1$或$A_{n}$,显然$\sum_{i=1}^{n}a_{i}\equiv 0(mod\ 2)$,因此$a_{n}$的取值可以直接确定,进而不难发现$\frac{\sum_{i=1}^{n}a_{i}}{2}$已经取到上限

换言之,若$\sum_{i=1}^{n}A_{i}$为偶数,则取到最大值仅有$a_{i}=A_{i}$时(方案数为1),否则即对每一个$i$判断是否可以令$a_{i}=A_{i}-1$且$\forall j\ne i,a_{j}=A_{j}$,按之前的方式求出$B_{i-1}$和$B_{i}$的区间即可

时间复杂度为$o(n\log n)$(调整$B_{i-1}$和$B_{i}$),可以通过

(代码中转移的部分有点丑)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mod 998244353
5 #define ll long long
6 priority_queue<pair<int,int> >q;
7 int n,ans,a[N],b[N],vis[N],L[N],p[N];
8 int get(int k,int p){
9 if ((k&1)!=p)k--;
10 return k;
11 }
12 int calc(int x,int y){
13 a[x]=b[x],a[y]=b[y-1];
14 int s=0;
15 for(int i=x;i<=y;i++)s^=(a[i]&1);
16 if (!s)return 1;
17 L[x-1]=p[x-1]=0;
18 for(int i=x;i<=y;i++){
19 p[i]=(p[i-1]^(a[i]&1));
20 if (L[i-1]>=a[i])L[i]=L[i-1]-a[i];
21 else L[i]=get(max(a[i]-get(b[i-1],p[i-1]),0)+1,p[i]);
22 }
23 int LL=0,pp=0,ans=0;
24 for(int i=y;i>=x;i--){
25 int x=get(b[i-1],p[i-1]),y=get(b[i],pp);
26 if (a[i]-1<=x+y){
27 if (abs(x-y)<=a[i]-1)ans++;
28 else{
29 if (a[i]-1<=x+y-2){
30 if ((x>y)&&(L[i-1]<=x-2))ans++;
31 if ((x<y)&&(LL<=y-2))ans++;
32 }
33 }
34 }
35 if (LL>=a[i])LL-=a[i];
36 else LL=get(max(a[i]-get(b[i],pp),0)+1,(pp^(a[i]&1)));
37 pp^=(a[i]&1);
38 }
39 return ans;
40 }
41 int main(){
42 scanf("%d",&n);
43 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
44 for(int i=1;i<n;i++)scanf("%d",&b[i]);
45 for(int i=0;i<=n;i++)q.push(make_pair(-b[i],i));
46 while (!q.empty()){
47 int k=q.top().second;
48 q.pop();
49 if (vis[k])continue;
50 vis[k]=0;
51 if ((k)&&(b[k-1]>a[k]+b[k])){
52 b[k-1]=a[k]+b[k];
53 q.push(make_pair(-b[k-1],k-1));
54 }
55 if ((k<n)&&(b[k+1]>a[k+1]+b[k])){
56 b[k+1]=a[k+1]+b[k];
57 q.push(make_pair(-b[k+1],k+1));
58 }
59 }
60 int lst=ans=1;
61 for(int i=2;i<=n;i++)
62 if (a[i]>=b[i-1]+b[i]){
63 int x=b[i];
64 b[i]=0,ans=(ll)ans*calc(lst,i)%mod;
65 lst=i,b[i-1]=0,b[i]=x;
66 }
67 printf("%d\n",ans);
68 return 0;
69 }

[atAGC054F]Decrement的更多相关文章

  1. Interlocked.Increment 方法 和Interlocked.Decrement 方法作用

    Interlocked.Increment 方法:让++成为原子操作:Interlocked.Decrement 方法让--成为原子操作.什么叫原子操作呢.就是不会被别人打断,因为C#中的一个语句,编 ...

  2. STL——increment/decrement/dereference操作符

    increment/dereference操作符在迭代器的实现上占有非常重要的地位,因为任何一个迭代器都必须实现出前进(increment,operator++)和取值(dereference,ope ...

  3. 只有 assignment、call、increment、decrement 和 new 对象表达式可用作语句

    错误信息:只有 assignment.call.increment.decrement 和 new 对象表达式可用作语句: 分析:发生这种情况一般是在赋值时把“=”写成了“==”,例如:textBox ...

  4. increment/decrement/dereference

    #include <vector> #include <deque> #include <algorithm> #include <iostream> ...

  5. C#原子操作(Interlocked.Decrement和Interlocked.Increment)

    一.概念 在多线程环境中,不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程). 二.类 System.Threadin ...

  6. ITEM M6 自增(INCREMENT)、自减(DECREMENT)操作符前缀形式与后缀形式的区别

    前缀自增 UPInt & UPint::operator++() { *this+=1; return *this; } 后缀自增 const UPInt & UPint::opera ...

  7. 【M6】区别increment/decrement操作符的前置(prefix)和后置(postfix)形式

    1.考虑++(--的情况是一样的),前置是累加然后取出,后置是取出然后累加. 2.重载方法根据形参表的不同区分,问题来了,前置和后置形式都没有形参,因此没法区分.怎么办? 对于后置增加一个形参int, ...

  8. increment/decrement/dereference操作符

    标题以上分别对于++/--/* #include <iostream> #include <cstddef> using namespace std; class INT { ...

  9. [atARC086F]Shift and Decrement

    将$A$操作看作直接除以2(保留小数),最终再将$a_{i}$取整 记$k$表示$A$操作的次数,$p_{i}$表示第$i$次$A$和第$i+1$次$A$之间$B$操作的次数(特别的,$p_{0}$为 ...

随机推荐

  1. SpaCy下载及安装

    SpaCy可以说是坑多到怀疑人生.. 但是看在它那么功能那么强大的份上,我还是决定原谅它哈哈哈~ 1.首先用官网给的命令快速安装纯属扯淡..(结果就是一直拒绝你的连接) 官网:https://spac ...

  2. Python读取网页表格数据

    学会了从网格爬取数据,就可以告别从网站一页一页复制表格数据的时代了. 说个亲身经历的事: 以前我的本科毕业论文是关于"燃放烟花爆竹和空气质量"之间关系的,就要从环保局官网查资料. ...

  3. YouTube爬虫下载

    最近在想用爬虫写youtube网站下载学习视频,找了好多资料也没有有个有用的. 真不容易找到几行代码,代码实现很简单,基于youtube_dl 来之不易,仅参考 from __future__ imp ...

  4. 树莓派4B学习札记

    防静电 树莓派比较容易被静电损坏,要做好以下预防措施 使用的时候不要用手去触摸PCB和针脚!特别是上电之后! 拿板卡的时候,要习惯性拿板卡的边缘 勤洗手,勤摸墙壁,释放身上的静电 系统安装 8GB以上 ...

  5. 从零到熟悉,带你掌握Python len() 函数的使用

    摘要:本文为你带来如何找到长度内置数据类型的使用len() 使用len()与第三方数据类型 提供用于支持len()与用户定义的类. 本文分享自华为云社区<在 Python 中使用 len() 函 ...

  6. css单位px,em,rem区别

    在css中单位长度用的最多的是px.em.rem,这三个的区别是: px是固定的像素,一旦设置了就无法因为适应页面大小而改变. em和rem相对于px更具有灵活性,他们是相对长度单位,意思是长度不是定 ...

  7. sql递归查询部门数据

    1 with cte as 2 ( 3 select a.DepartCode,a.DepartName,a.ParentDepartCode from tbDeparts a where Paren ...

  8. 【Linux命令063】Linux非常简单常用的入门命令

    Linux常用命令 这是一篇我在公众号上发布的文章,还算较为受欢迎. 博客园这边荒废好长时间了,主要是最近一年经常撰写的文章都是Linux相关的入门文章. 不知道是否能通过博客园的首页审核. 1.cd ...

  9. 2021.9.22考试总结[NOIP模拟59]

    T1 柱状图 关于每个点可以作出两条斜率绝对值为\(1\)的直线. 将绝对值拆开,对在\(i\)左边的点\(j\),\(h_i-i=h_j-j\),右边则是把减号换成加号. 把每个点位置为横坐标,高度 ...

  10. SpringCloud 2020.0.4 系列之Hystrix看板

    1. 概述 老话说的好:沉默是金,有时适当的沉默,比滔滔不绝更加有效. 言归正传,前面我们聊了有关 Hystrix 降级熔断的话题,今天我们来聊聊如何使用 turbine 和 hystrix dash ...