首页 > 其他 > 详细

AGC037C Numbers on a Circle(神奇思路)

时间:2019-09-26 23:47:35      阅读:90      评论:0      收藏:0      [点我收藏+]

Atcoder 全是神仙题……

先变成能不能从 \(b\)\(a\)。操作变成一个数减掉旁边两个数。

考虑里面最大的且不和 \(a\) 中相等的那个数。它两边的数此时都不能操作,否则就减到非正数了。

而且应该要一直对这一位进行操作,直到等于 \(a_i\) 或者不是最大值为止。这样两边的数才能操作,或者真正确定无解。

用个堆模拟即可。

我的代码中复杂度……大概是两个 \(\log\) 吧。(辗转相除算一个)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=200020,mod=998244353;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
    int x=0,f=0;char ch=getchar();
    while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
struct item{
    int val,id;
    bool operator<(const item &i)const{return val<i.val;}
};
int n,a[maxn],b[maxn];
ll ans;
priority_queue<item> pq;
int main(){
    n=read();
    FOR(i,1,n) a[i]=read();
    FOR(i,1,n){
        b[i]=read();
        if(a[i]!=b[i]) pq.push((item){b[i],i});
    }
    while(!pq.empty()){
        int id=pq.top().id;pq.pop();
        int pre=id==1?n:id-1,nxt=id==n?1:id+1;
        if(b[id]-a[id]<b[pre]+b[nxt]) return puts("-1"),0;
        ans+=(b[id]-a[id])/(b[pre]+b[nxt]);
        b[id]-=(b[id]-a[id])/(b[pre]+b[nxt])*(b[pre]+b[nxt]);
        if(b[id]==a[id]) continue;
        pq.push((item){b[id],id});
    }
    printf("%lld\n",ans);
}

AGC037C Numbers on a Circle(神奇思路)

原文:https://www.cnblogs.com/1000Suns/p/11594718.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!