AT5160-[AGC037C]Numbers on a Circle【贪心,堆】
正題
題目鏈接:https://www.luogu.com.cn/problem/AT5160
題目大意
給出兩個長度為nnn的環序列aaa和bbb,每次你可以讓aaa中的一個數變為它和相鄰兩個的和。
求最少的步數將aaa變為bbb。
1≤n≤105,1≤ai,bi≤1091\leq n\leq 10^5,1\leq a_i,b_i\leq 10^91≤n≤105,1≤ai?,bi?≤109
解題思路
被藍題D爛了。
考慮反過來做,每次操作為Bi=Bi?Bi?1?Bi+1B_i=B_i-B_{i-1}-B_{i+1}Bi?=Bi??Bi?1??Bi+1?。
然后考慮怎么搞這個東西,注意到BiB_iBi?不能夠減到負數所以同理也不能減到小于AiA_iAi?,考慮如果對于一個Bi≥Bi?1+Bi+1B_i\geq B_{i-1}+B_{i+1}Bi?≥Bi?1?+Bi+1?那么此時位置i?1i-1i?1和i+1i+1i+1顯然都是不能動的,那么我們動BiB_{i}Bi?就一定是最優的。
還有如果Bi=AiB_i=A_iBi?=Ai?時那么BiB_iBi?就是不可以再操作的了。
具體地我們每次找到最大的可操作的BiB_iBi?,然后把它減到不能再減即可,然后過程中判斷是否無解即可。
由于每次至少減半所以每個數應該會操作最多logloglog次。
時間復雜度:O(nlog?nlog?w)O(n\log n\log w)O(nlognlogw)
code
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define ll long long #define mp(x,y) make_pair(x,y) using namespace std; const ll N=2e5+10; ll n,a[N],b[N],ans; priority_queue<pair<int,int> > q; ll pl(ll x){return (x==1)?n:(x-1);} ll pr(ll x){return (x==n)?1:(x+1);} signed main() {scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);for(ll i=1;i<=n;i++){scanf("%lld",&b[i]),q.push(mp(b[i],i));if(a[i]>b[i])return puts("-1")&0;}while(!q.empty()){ll x=q.top().second;q.pop();if(b[x]==a[x])continue;ll d=b[pl(x)]+b[pr(x)];if(b[x]-d<a[x])break;ans+=(b[x]-a[x])/d;b[x]-=(b[x]-a[x])/d*d;if(b[x]!=a[x])q.push(mp(b[x],x));}if(q.size())puts("-1");else printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的AT5160-[AGC037C]Numbers on a Circle【贪心,堆】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 路由器穿墙王十大品牌排行榜
- 下一篇: CF1242C-Sum Balance【