写的主席树,WA了,给个 hack 就行,谢谢!
#include<bits/stdc++.h>
#define int __int128
using namespace std;
const int N=2e5+5;
int n,m,a[N],sum[N],pre2[N],b[N],pre[N],rt[N],ans,cnt,ls[20*N],rs[20*N],S[20*N];
int read(){
int f=1,x=0;
char s=getchar();
while(s<'0'||s>'9'){
if(s=='-') f=-1;
s=getchar();
}
while(s>='0'&&s<='9'){
x=x*10+s-'0';
s=getchar();
}
return x*f;
}
void write(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
void modify(int sto,int &x,int l,int r,int h,int v){
if(!x) x=++cnt;
if(l==r){
S[x]=S[sto]+v;
return;
}
int mid=(l+r)/2;
if(h<=mid){
rs[x]=rs[sto];
modify(ls[sto],ls[x],l,mid,h,v);
}
else{
ls[x]=ls[sto];
modify(rs[sto],rs[x],mid+1,r,h,v);
}
S[x]=S[ls[x]]+S[rs[x]];
}
int query(int x,int l,int r,int L,int R){
if(!x) return 0;
if(l>=L&&r<=R) return S[x];
int mid=(l+r)/2,ret=0;
if(L<=mid) ret+=query(ls[x],l,mid,L,R);
if(R>mid) ret+=query(rs[x],mid+1,r,L,R);
return ret;
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
a[i]=read();
sum[i]=sum[i-1]+a[i];
b[i]=sum[i]/m;
pre2[i]=pre2[i-1]+b[i];
pre[i]=pre[i-1]+sum[i];
modify(rt[i-1],rt[i],1,m,sum[i]%m,1);
}
for(int i=1,j=0,cnt=0;i<=n;i++){
cnt+=sum[i];
ans+=sum[i]%m;
while(sum[i]-sum[j]>=m&&(j+1)<=n) cnt-=sum[j++];
if(j) ans+=(i-j+1)*sum[i]-cnt;
else ans+=i*sum[i]-cnt;
if(j){
int num=query(rt[j-1],1,m,sum[i]%m+1,m-1);
ans+=sum[i]*(j-1)-pre[j-1]-(-pre2[j-1]+b[i]*(j-1)-(num))*m;
}
}
write(ans);
return 0;
}