具体问题
子任务
70% 的测试数据满足 1≤n≤200 且 n<N≤1000;
全部的测试数据满足 1≤n≤105 且 n<N≤10^9。
提示
需要注意,输入数据 [A1⋯An] 并不一定均匀分布在 (0,N) 区间,因此总误差 error(A) 可能很大。
接下来放上我一开始想错了的代码(留作纪念)emmm,这个代码有点一言难尽,我以为能通过所有测试样例就是对的,但事实并不是这样,应该是某个情况没有考虑到。
错误代码
#include<iostream>
#include<cmath>
using namespace std;
long long n,N,a[100001],r,sum1,sum2,l,e;
//把0看成-1加起来求和,然后让两个和相减求绝对值
int main(){
cin>>n>>N;
a[0]=0;
a[n+1]=N;
sum1=0;
sum2=0;
for(long long i=1;i<=n;i++){
cin>>a[i];
}
for(long long i=1;i<=n+1;i++){
l=a[i]-a[i-1];
if(i==1){
sum1-=l;
}else {
sum1+=l*(i-1);
}
}
r=N/(n+1);
for(long long i=0;i<=N-1;i++){
long long k=i/r;
if(k==0){
sum2-=1;
}else{
sum2+=k;
}
}
e=abs(sum1-sum2);
cout<<e<<endl;
return 0;
}
再放上70分超时的暴力求解代码,就是说很菜了。
超时代码
#include<stdio.h>
#include<iostream>
#include<math.h>
typedef long long ll;
#define l1 100001
using namespace std;
ll n, N,a[l1],f[l1],g[l1],result,k;
int main() {
cin >> n >> N;
a[n+1]=N;
for (ll i = 1; i <= n; i++) {
cin>>a[i];
}
ll r = N / (n + 1);
for (ll i = 1; i <= n+1; i++) {
ll l=a[i]-a[i-1];
ll m=0;
while(m<l){
f[k]=i-1;
k++;
m++;
}
}
for (ll i = 0; i < N; i++) {
g[i] = i / r;
}
for (ll i = 0; i < N; i++) {
result += abs(g[i] - f[i]);
}
cout<<result;
return 0;
}
最后放上y总的讲解视频 AcWing 4281. 序列查询新解(AcWing杯 - 周赛) - AcWing,看看视频可能也许就会明白了。
AC代码
#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL;
const int M = 1e5 + 10;
int n, N;
int A[M];
int R;
LL error;
LL get(int l, int r){
if (l / R == r / R) return (LL)(l / R) * (r - l + 1);
int a = l / R + 1, b = r / R - 1;
LL res = (a - 1) * (LL)(a * R - l); //left
res += (b + 1) * (LL)(r - (b * R + R) + 1); //right
res += (LL)(b - a + 1) * (a + b) / 2 * R; //mid,等差数列求和
return res;
}
int main(){
cin >> n >> N;
for (int i = 1; i <= n; i ++ ) cin >> A[i];
A[n + 1] = N;
R = N / (n + 1);
for (int i = 0; i <= n; i ++ ){
int l = A[i], r = A[i + 1] - 1;
if (i >= r / R || i <= l / R){
error += abs((LL)(r - l + 1) * i - get(l, r));
}
else{
int mid = i * R;
error += abs((LL)(mid - l + 1) * i - get(l, mid));//left
error += abs((LL)(r - mid + 1) * i - get(mid, r));//right
}
}
cout << error;
return 0;
}