[CF1119G]Get Ready for the Battle
Posted StaroForgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1119G]Get Ready for the Battle相关的知识,希望对你有一定的参考价值。
Get Ready for the Battle
题解
由于这里是写题解,我当然不会写那个我自己都觉得是错的乱贪心。
所以,让我们来看看正解是怎么做的。
首先,我们的轮数下限肯定是
⌈
∑
a
i
n
⌉
\\lceil\\frac{\\sum a_{i}}{n}\\rceil
⌈n∑ai⌉,我们肯定不可能比这个还早出解。
但我们可以思考如何在这个范围内构造出一组解。
显然,如果我们要达到这个限制,这个就要求我们最多有一个连续的轮数会超标,而且这个超标是要尽可能集合在一个人身上的。
那我们不妨就一个一个人地加过来,直到加在最后一个人身上时才出现超标的状况。
所以,我们不妨最开始就拿
n
n
n 的整块去填,看将这个
n
n
n 的整块需要分成哪些才能够让前面这些都不超。
如果我们要让我们填到
a
i
a_{i}
ai 时不超,那么我们显然需要能填出一个
∑
j
=
1
i
a
j
%
n
\\sum_{j=1}^{i}a_{j} \\%n
∑j=1iaj%n 的方法,这样才能让我们能在前面都被整块覆盖的情况下将这些刚好填满。
于是我们可以得到
m
m
m 个前缀和,当然最后一个前缀和肯定是
n
n
n,其通过差分得到的数组顺序填过去刚好能让在前面
m
−
1
m-1
m−1 个
a
i
a_{i}
ai 我们绝对不会浪费任何一个位置。最后一个当然会超了
我们既然
a
a
a 的顺序与大小已经定了,我们只需要再用一个指针维护我们在填这个数时填到哪个前缀和就可以知道我们的这个数是放在哪里的了。
时间复杂度 O ( m log m + n + ∑ a ) O\\left(m\\log\\,m+n+\\sum a\\right) O(mlogm+n+∑a)。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL;
typedef long double ld;
const int INF=0x3f3f3f3f;
const int mo=1e9+7;
const int inv2=499122177;
const double jzm=0.997;
const int zero=15;
const int lim=1000000;
const int n1=200;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-5;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;a%=p;while(s){if(s&1)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1;}return t;}
int n,m,a[MAXN],b[MAXN],c[MAXN];
int turn(int x){if(x%n)return x%n;return n;}
signed main(){
read(n);read(m);
for(int i=1;i<=m;i++)read(a[i]),a[i]+=a[i-1];
if(a[m]%n)a[m]+=n-(a[m]%n);int T=a[m]/n,sum=0;
for(int i=1;i<=m;i++)b[i]=turn(a[i]);sort(b+1,b+m+1);
printf("%d\\n",T);
for(int i=1;i<=m;i++)c[i]=b[i]-b[i-1],printf("%d ",c[i]);puts("");
for(int i=1,j=1;i<=T;i++,puts(""))
for(int k=1;k<=m;k++){
while(j<m&&sum>=a[j])j++;
printf("%d ",j);sum+=c[k];
}
return 0;
}
谢谢!!!
以上是关于[CF1119G]Get Ready for the Battle的主要内容,如果未能解决你的问题,请参考以下文章
CF622F The Sum of the k-th Powers (拉格朗日插值)
CF609E Minimum spanning tree for each edge
CF3A Shortest path of the king
[题解] CF622F The Sum of the k-th Powers
CF gym 10326040th Petrozavodsk Programming Camp, Day 5,2021.2.3 水题2题