标签:algorithm
codeforces 526 e Transmitting Levels/*codeforces 526 e
题意:
给出n个数a1,a2,...,an,这n个数首尾相接形成一个环。
如:1 2 3
(1,2) (2,3) (3,1) 相连
现在再给出q个询问,每个询问为一个b,求把这n个数分成相连的m段,使得每段的和不超过b,求m的最小值。
限制:
2 <= n <= 1e6
1 <= q <= 50
1 <= ai <= 1e9
max(ai) <= b <= 1e15
思路:
先找出一个最小的段,从最小的段中枚举起点,取最小值即为答案。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL __int64
const int N=1e6+5;
LL a[N];
LL sum[2*N];
int nxt[N];
int deal(int st,int n){
int cnt=0;
int p=st;
while(p<n){
++cnt;
p=nxt[p%n];
}
while(p%n<st){
++cnt;
p=nxt[p%n];
}
return cnt;
}
void gao(LL b,int n){
int st=0,len=n;
int p=0,q=0;
while(p<n){
while(q<=2*n && sum[q]-sum[p]<=b){
++q;
}
if(q-p-1>n){ puts("1"); return ; }
else{
nxt[p]=q-1;
int tmp=q-p-1;
if(tmp<len){
len=tmp;
st=p;
}
}
++p;
}
int ans=n;
for(int i=st;i<=st+len;++i){
ans=min(ans,deal(i%n,n));
}
printf("%d\n",ans);
}
void In(int &x){
char c; x=0; c=getchar();
int sign=1;
while(!(c>='0'&&c<='9' || c=='-')) c=getchar();
if(c=='-') sign=-1,c=getchar();
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
x*=sign;
}
void In(LL &x){
char c; x=0; c=getchar();
int sign=1;
while(!(c>='0'&&c<='9' || c=='-')) c=getchar();
if(c=='-') sign=-1,c=getchar();
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
x*=sign;
}
int main(){
int n,q;
In(n);
In(q);
for(int i=0;i<n;++i){
In(a[i]);
}
sum[0]=0;
for(int i=0;i<2*n;++i){
sum[i+1]=sum[i]+a[i%n];
}
LL b;
for(int i=0;i<q;++i){
In(b);
gao(b,n);
}
return 0;
}codeforces 526 e Transmitting Levels
标签:algorithm
原文地址:http://blog.csdn.net/whai362/article/details/45073373