题目传送门

题意

这道题被某大佬改编拿来出成考试题,是长这个样子的:

好的,其实这才是真正的题意:

给定初始序列和最终序列,每次选择一个数变成自己和相邻2个数的和。问初始序列是否可以变为最终序列,若可以,问最少需要多少次。

分析

发现这道题有很多种操作方式,就算是写搜索暴力都不是很好写。

正难则反,考虑从末状态到初状态,就是一直减去左右两边的数。

如果中间的数大于两边的数之和,那么中间那个数一定要被操作(设$a,b,c$分别为$i-1,i,i+1$上的$B$值)
而且在$b>a+c$条件不被破坏时,如果不对$b$操作,那么$a,c$也不会被操作(操作之后为负数,不合法)
只要$b>a+c$并且$Bi>Ai$ $b$就要一直减去$(a+c)$
由于是一定要减 是必要的 所以也最小

$b>a+c$的条件就是在if(...)-1 那个地方判断的 也可以写成if(!step) 就是判断操作次数至少为$1$次
如果不能操作(操作就成负数)那就不能有解 如果可以操作 下取整操作次数是一定要做的 哪怕只有一次都要做
做完之后 如果满足了$Ai==Bi$那最好 就ok啦
但如果不满足 根据step的算法 就是再减一次就变成负数 这个时候$b<a+c$了
就不一定需要操作 所以继续塞到队列里面等着有朝一日继续操作

用优先队列呢,也是因为"在$b>a+c$条件不被破坏时,如果不对$b$操作,那么$a,c$也不会被操作(操作之后为负数)"
如果不先对最大的那个数操作 那么后面也就没有办法操作。

基本上就是这样了。

不过还要注意开$long$ $long$(具体次数好像不是很好算,这种不好估计的情况还是都开起比较保险)

代码

 #include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
#define N 200005
#define ll long long
#define fst first
#define snd second
//环:1:2,n n:n-1,1
int n,a[N],b[N];
ll ans;//记得开ll
inline int rd()
{
int f=,x=;char c=getchar();
while(c<''||''<c){if(c=='-')f=-f;c=getchar();}
while(''<=c&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return f*x;
}
priority_queue<pair<int,int> >Q;
//pair定义优先队列 先按first 再按second 自动排序
int main()
{
//freopen("hopeless.in","r",stdin);
//freopen("hopeless.out","w",stdout);
n=rd();
for(int i=;i<=n;i++)
a[i]=rd();
for(int i=;i<=n;i++)
{
b[i]=rd();
if(a[i]!=b[i]) Q.push(make_pair(b[i],i));
}
while(!Q.empty())
{
pair<int,int> now=Q.top();Q.pop();
int i=now.snd;
/*int pre=i-1,suf=i+1;
if(pre==0) pre=n;
if(suf==n+1) suf=1;
int step=(b[i]-a[i])/(b[pre]+b[suf]);
*/
int pre=(i+n-)%n+,suf=i%n+;
int step=(b[i]-a[i])/(b[pre]+b[suf]);
if(b[i]-b[pre]-b[suf]<a[i])
{
puts("-1");
return ;
}
ans+=step;
b[i]-=step*(b[pre]+b[suf]);
if(a[i]!=b[i]) Q.push(make_pair(b[i],i));
}
printf("%lld\n",ans);
return ;
}

Code

AGC037 C Numbers on a Circle【思维】的更多相关文章

  1. AGC037C Numbers on a Circle(神奇思路)

    Atcoder 全是神仙题-- 先变成能不能从 \(b\) 到 \(a\).操作变成一个数减掉旁边两个数. 考虑里面最大的且不和 \(a\) 中相等的那个数.它两边的数此时都不能操作,否则就减到非正数 ...

  2. AGC037C Numbers on a Circle【构造】

    从后往前做,每次将\(B_i\)减去相邻两个数,注意如果最大的数没有变成初始状态,那么肯定要减,否则相邻两边的就减不了,所以用堆维护.根据辗转相除的复杂度,\(O(n\log^2 n)\). #inc ...

  3. AGC037C Numbers on a Circle

    题目大意 给你一个序列a和序列b 每次操作是a[i]+=a[i-1]+a[i+1] 问a经过最少几次操作可以得到b 分析 用堆维护a 每次取出最大的 撤销操作直到不能撤销 将新数放入堆 不断维护即可 ...

  4. Codeforces Beta Round #94 div 1 D Numbers map+思路

    D. Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  5. CodeForces 128D Numbers 构造

    D. Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  6. ATcoder Grand Contest总结

    最前面: AT的题都很有思维难度,总结一下一些AT的常规操作 1.对于有操作的题目,如果正面推不行的话考虑倒推,将操作转化,寻找更好的性质 2.模型转化,看到某一种的计算的式子,需要考虑有没有更简化的 ...

  7. crossplatform---Node.js Applications with VS Code

    Node.js is a platform for building fast and scalable server applications using JavaScript. Node.js i ...

  8. uva 524 prime ring problem——yhx

      Prime Ring Problem  A ring is composed of n (even number) circles as shown in diagram. Put natural ...

  9. Daily Scrum – 1/12

    Meeting Minutes Merge Wordlist & Word Recite entry. (P0) – Done. Remove "Word Challenge&quo ...

随机推荐

  1. Spring资源

    资源 官网:http://spring.io 文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/.htt ...

  2. Mac 安装RN android开发环境

    前言 前面介绍了MAC 安装,再来讲讲mac 安装 安卓的开发环境 首先貌似很多Mac自带安卓JDK ,你可以在终端上输入java -version 看是否已经有java开发环境. 如果没有java开 ...

  3. ssky-keygen + ssh-copy-id 无密码登陆远程LINUX主机【OK】

    ssky-keygen + ssh-copy-id 无密码登陆远程LINUX主机[OK]     使用下例中ssky-keygen和ssh-copy-id,仅需通过3个步骤的简单设置而无需输入密码就能 ...

  4. Tomcat部署多个Springboot项目报错 InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat

    在一个tomcat服务器下部署了多个采用阿里druid作为数据连接池,结果启动报错.原因是不能在一个tomcat服务器下不能直接部署多个druid作为数据连接池的项目,需要配置. 解决办法: 在spr ...

  5. 科普TPF知识

    https://tieba.baidu.com/p/4926092734?see_lz=1&pn=1 707680700 https://tieba.baidu.com/p/492609273 ...

  6. centos7安装dockers

    安装Docker我是虚拟机装的Centos7,linux 3.10 内核,docker官方说至少3.8以上,建议3.10以上(ubuntu下要linux内核3.8以上, RHEL/Centos 的内核 ...

  7. 51 Nod 不重叠的线段

    #include<bits/stdc++.h> #define in(X) scanf("%d",&X) #define out(X) printf(" ...

  8. Codeforces Round #578 (Div. 2) Solution

    Problem A Hotelier 直接模拟即可~~ 复杂度是$O(10 \times n)$ # include<bits/stdc++.h> using namespace std; ...

  9. 1209F - Koala and Notebook

    这场比赛没打,看同学fst了,于是来看看. 这道题看似简单,但是没想清楚细节真的不太行.像现在熬到十一点左右,脑子真的不行. 首先显然位数越小越好,因为每一位要比较,不如拆点.此时要拆成两条有向链(开 ...

  10. Compress Words

    E. Compress Words 直接套 KMP 即可(那为什么打 cf 的时候没有想到...),求出后一个单词(word)的前缀数组,然后从前面已得的字符串的末尾 - word. length ( ...