CF1119G. Get Ready for the Battle
CF1119G. Get Ready for the Battle
題目描述
Solution
妙妙構(gòu)造題。
考慮這樣一個過程:所有人一起打第一個怪,每次打nnn,最后剩下k1<nk_1<nk1?<n,就找一些加起來正好為k1k_1k1?的組打掉k1k_1k1?,剩下的n?k1n-k_1n?k1?打第二個怪,然后重復(fù)打nnn,余數(shù)k2k_2k2?找一些組正好打掉這樣一個過程,直到剩下最后一個怪,打玩n?km?1n-k_{m-1}n?km?1?,再一直打nnn到非正。
若能夠構(gòu)造s1..ms_{1..m}s1..m?,滿足可以配成k1...km?1k_1...k_{m-1}k1?...km?1?中的任意數(shù)。
即可求出答案為?∑ain?\lceil \frac{\sum a_i}{n} \rceil?n∑ai???。
于是我們將kkk排序,令si=ki+1?kis_i=k_{i+1}-k_{i}si?=ki+1??ki?,sm=n?km?1s_m=n-k_{m-1}sm?=n?km?1?,可以滿足任意kik_iki?為sss前綴和中的一個。
構(gòu)造完sis_isi?之后,事實上只需要用a1a_1a1?依次減s[1...m]s[1...m]s[1...m],減完s[m]s[m]s[m]之后再從s[1]s[1]s[1]開始減。若減的過程中a1≤0a_1\leq 0a1?≤0,則用a2a_2a2?繼續(xù)減,直到am≤0a_m\leq 0am?≤0。
事實上這樣做,a1..(m?1)a_{1..(m-1)}a1..(m?1)?都會減為0,達到最優(yōu)解。
原因參照下例:
a1?n?n?...?n?k1=0a_1-n-n-...-n-k_1=0a1??n?n?...?n?k1?=0
a2?(n?k1)%n?n?n?...?n?k2=0a_2-(n-k1)\%n-n-n-...-n-k_2=0a2??(n?k1)%n?n?n?...?n?k2?=0
a3?(n?k2)%n?n?n?...?n?k3=0a_3-(n-k2)\%n-n-n-...-n-k_3=0a3??(n?k2)%n?n?n?...?n?k3?=0
..................
am?(n?km?1)%n?n?n?...?n≤0a_m-(n-k_{m-1})\%n-n-n-...-n\leq0am??(n?km?1?)%n?n?n?...?n≤0
kik_iki?與(n?ki)(n-k_i)(n?ki?)配成一段連續(xù)的s[1..m]s[1..m]s[1..m]。
且不可能出現(xiàn)如下情況:
a1?n?n?...?n?k1=0a_1-n-n-...-n-k_1=0a1??n?n?...?n?k1?=0
a2?k2=0(a2<(n?k1)%n)a_2-k_2=0\;\;(a_2<(n-k1)\%n)a2??k2?=0(a2?<(n?k1)%n)
..................
因為k2=(a1+a2)%nk_2=(a_1+a_2)\%nk2?=(a1?+a2?)%n,因此k2=(k1+k2)%nk_2=(k_1+k_2)\%nk2?=(k1?+k2?)%n,則k1%n=0k_1\%n=0k1?%n=0,則k1=0k_1=0k1?=0。
因此按此過程一定是按s[1..m]s[1..m]s[1..m]連續(xù)減下去,減完s[m]s[m]s[m],從s[1]s[1]s[1]繼續(xù)減下去。
Code(講述凌亂,理解代碼體驗極佳)
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cassert> #include <string.h> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B) #define PB(A) push_back(A) #define SIZE(A) ((int)A.size()) #define LEN(A) ((int)A.length()) #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define fi first #define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; } template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll; typedef unsigned long long ull; typedef long double lod; typedef pair<int,int> PR; typedef vector<int> VI;const lod eps=1e-11; const lod pi=acos(-1); const int oo=1<<30; const ll loo=1ll<<62; const int MAXN=1000005; const ll INF=1ll<<60; /*--------------------------------------------------------------------*/ inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } VI Ans; int a[MAXN],b[MAXN],s[MAXN]; int main() {int n=read(),m=read(),sum=0; b[1]=n;for (int i=1;i<=m;i++) sum+=(a[i]=read()),b[i+1]=sum%n;sort(b+1,b+m+1);for (int i=1;i<=m;i++) s[i]=b[i]-b[i-1];for (int i=1,id=0;i<=m;i++){int t=a[i];while (t>0) Ans.PB(i),t-=s[id%m+1],id++;}printf("%d\n",(sum-1)/n+1);while (Ans.size()%m) Ans.PB(1);for (int i=1;i<=m;i++) printf("%d%c",s[i]," \n"[i%m==0]);for (int i=0;i<Ans.size();i++) printf("%d%c",Ans[i]," \n"[(i+1)%m==0]);return 0; }總結(jié)
以上是生活随笔為你收集整理的CF1119G. Get Ready for the Battle的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄绿色鼻涕伴随头疼是什么病?
- 下一篇: CF1158D. Beautiful A