题目描述
输入
输出
样例输入
样例1
3 10
2 5 8
样例2
9 10
1 2 3 4 5 6 7 8 9
样例3
2 10
1 3
样例输出
样例1
5
样例2
0
样例3
6
子任务
源代码
70分:
#include <iostream>
#include <math.h>
using namespace std;
int main (){
int n,N;
cin>>n>>N;
long double *f=new long double [N+1];
long double *g=new long double [N+1];
long double *t=new long double [N+1];
long double *c=new long double [N+1];
int rate=0;
int temp=0;
int i=0;
int result=0;
int h=0;
int count=0;
int k=0;
f[0]=0;
g[0]=0;
c[0]=0;
t[0]=0;
for (i = 1; i <=n ; i++) {
cin>>temp;
t[i]=temp;
c[i-1]=t[i]-t[i-1];
}
c[i-1]=N-t[i-1];
rate=ceil((double )(N/(n+1)));
for (int j = 0; j < N; j++) {
g[j]= ceil((double )(j/rate));
}
for (int j = 0; j < N; j++) {
if (c[h]!=count){
count++;
}
else{
h++;
k++;
count=1;
}
f[j]=abs(g[j]-k);
}
for (int j = 0; j <N ; j++) {
result+=f[j];
}
cout<<result<<endl;
return 0;
}
100分:
#include <iostream>
#include <cmath>
using namespace std;
#define ll long long
// 求f数列某个区间的值。x表示区间的右边界开区间,y表示左边界闭区间,i表示区间内的任意元素值为i
ll getFSum(int x, int y, int i) {
return (ll)(x - y) * i;
}
// 计算g数列前pos项的和
ll getGSum(int pos, int r) {
int st = 0;
// 前pos项中完整长度为r的区间的个数
int seqNum = (pos + 1) / r;
// 前pos项中最后一个不完整区间的个数,为0或1
int lastSeqNum = (pos + 1) % r == 0 ? 0 : 1;
// 千seqNum个区间的区间和
ll sum = (ll)seqNum * (seqNum - 1) / 2 * r;
// 最后一个区间中的值的和
ll lastSum = (ll)seqNum * lastSeqNum * ((pos + 1) % r);
return sum + lastSum;
}
// 计算yx区间内g-f的绝对值
ll getSum(int x, int y, int r, int i) {
int f, gMin, gMax, changedIndex;
ll sum = 0;
f = i;
gMin = y / r;
gMax = (x - 1) / r;
if(f >= gMax)
sum += getFSum(x, y, i) - (getGSum(x - 1, r) - getGSum(y - 1, r));
else if(f <= gMin)
sum += (getGSum(x - 1, r) - getGSum(y - 1, r)) - getFSum(x, y, i);
else {
for(int k = gMin; k <= gMax; k ++)
if(k >= i) {
changedIndex = y + (k - gMin) * r;
sum += getFSum(changedIndex, y, i) - (getGSum(changedIndex - 1, r) - getGSum(y - 1, r));
sum += (getGSum(x - 1, r) - getGSum(changedIndex - 1, r)) - getFSum(x, changedIndex, i);
break;
}
}
return sum;
}
int main() {
int n, N, x = 0, y, r;
ll sum = 0;
cin >> n >> N;
r = N / (n + 1);
for(int i = 0; i < n; i ++) {
y = x;
cin >> x;
if(x > y)
sum += getSum(x, y, r, i);
}
// 最后计算xN区间
sum += getSum(N, x, r, n);
cout << sum;
}
关于这题
70分 其实都是int 也是70分…
100分: 还是换个思路 不再计算每个的值 再计算 |f(i)-g(i)| 而是计算 一整个区间的|f(i)-g(i)|的值
g(i)的每r个数的值是一样的(可能存在最后的几个数 ,不足r个数,这个要单独讨论)
既然是要计算整个区间的值,去绝对值,就分两种情况,f(i)>=g(i) 和 f(i)<g(i)