AGC037C Numbers on a Circle

题目大意

给你一个序列a和序列b

每次操作是a[i]+=a[i-1]+a[i+1]

问a经过最少几次操作可以得到b

分析

用堆维护a

每次取出最大的

撤销操作直到不能撤销

将新数放入堆

不断维护即可

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define int long long
priority_queue<pair<int,int> >q;
int n,m,b[200100],a[200100],pre[200100],nxt[200100];
signed main(){
    int i,j,k,ans=0;
    scanf("%lld",&n);
    for(i=1;i<=n;i++)scanf("%lld",&a[i]);
    for(i=1;i<=n;i++){
      scanf("%lld",&b[i]);
      q.push(mp(b[i],i));
    }
    for(i=1;i<=n;i++){
      nxt[i]=i+1;
      pre[i]=i-1;
    }
    pre[1]=n;
    nxt[n]=1;
    while(!q.empty()){
      int x=q.top().se;
      q.pop();
      if(b[x]==a[x])continue;
      int y=pre[x],z=nxt[x];
      if(b[x]-b[y]-b[z]<a[x]){
          puts("-1");
          return 0;
      }
      k=b[x]-a[x];
      ans+=k/(b[y]+b[z]);
      b[x]=(k%(b[y]+b[z]))+a[x];
      if(a[x]!=b[x])q.push(mp(b[x],x));
    }
    cout<<ans<<"\n";
    return 0;
}
posted @ 2019-08-20 17:21  水题收割者  阅读(276)  评论(0编辑  收藏  举报