2022.2.28 练习 CSP 202112-2 序列查询新解
不容易啊…
一点教训: 既然数据量很大,干脆都设成long long,省得漏了哪里又扣分。第二题就是要找到数据的规律!!!
不明白的点: 最开始我把n,N和r
都设成了全局遍历变量,fun函数就有问题,不能返回结果,不知道为什么
#include <bits/stdc++.h>
using namespace std;
const int MAX=1e5+10;
//全都long long !
long long a[MAX]={0};
long long fun(long long i,long long r)
{
//找规律计算g的前缀和
if(i<0)
return 0;
else
{
return r*((i+1)/r-1)*((i+1)/r)/2+(i+1)%r*(i/r);
//开始写成了 r*((i+1)/r-1)*((i+1)/r)/2+(i+1)%r*i/r 只拿了25分,写代码一定要小心细节。。。都要掌握好
}
}
int main()
{
std::ios::sync_with_stdio(false);
long long n,N;
cin>>n>>N;
long long r=N/(n+1);
int tmp;
for(int i=1;i<=n;i++)
{
cin>>tmp;
a[i]=tmp;
}
a[0]=0;
a[n+1]=N;
long long sum=0;
for(int i=0;i<=n;i++)
{
long long left=a[i];
long long right=a[i+1]-1;//这里很巧妙
if(right/r <= i || left/r >= i)
{
sum+=abs(fun(right,r)-fun(left-1,r)-i*(right-left+1));
}
else
{
long long mid=r*i;
sum+=abs(fun(mid-1,r)-fun(left-1,r)-i*(mid-left));
sum+=abs(fun(right,r)-fun(mid-1,r)-i*(right-mid+1));
}
}
cout<<sum<<endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=1e5+10;
ll cal(int l,int r,int k)
{
int ls=l,rs=r;
if(l%k!=0) ls=(l/k+1)*k;
if(r%k!=0) rs=(r/k)*k;
ll sum=0;
sum+=(ls-l)*(l/k);
ll tmp=0;
int a=ls/k,n=(rs-ls)/k;
tmp=n*a+n*(n-1)/2;
tmp*=k;
sum+=tmp;
sum+=(r-rs+1)*(r/k);
return sum;
}
ll a[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
ll n,N;
cin>>n>>N;
ll k=N/(n+1);
for(int i=1;i<=n;i++) cin>>a[i];
a[0]=0; a[n+1]=N;
ll sum=0;
for(int i=1;i<=n+1;i++)
{
ll l=a[i-1],r=a[i]-1;
ll num=i-1;
ll lg=l/k,lr=r/k;
if(lg>=num || lr<=num)
{
ll sumf=(r-l+1)*num;
ll sumg=cal(l,r,k);
sum+=abs(sumg-sumf);
}
else
{
int mid=num*k;
ll sumf1=(mid-l)*num;
ll sumg1=cal(l,mid-1,k);
ll sumf2=(r-mid+1)*num;
ll sumg2=cal(mid,r,k);
sum+=abs(sumg1-sumf1);
sum+=abs(sumg2-sumf2);
}
}
cout<<sum;
return 0;
}