细节:
- 前缀和与ans可能会爆int
- 求第一个大于ai的b的下标j,可以二分。这里是双指针,从末尾开始扫描。
- 关于如何求cnt[j],双指针直接,控制大于ai的区间,记录当前区间长即可。
其他:
- 可读性和debug的难度负相关,原版,不妨多定义些明确的变量来承接上一个结果。比如这里取区间长也可以用指针作差,简洁有了,但是出错的潜力也提高了。
简化版 c++
#include <iostream>
#include <cstdio>
#include<algorithm>
using namespace std;
#define ffor(i,a,b) for(int i=a;i<b;i++)
#define rfor(i,a,b) for(int i=a;i>=b;i--)
#define out(x) cout<<x<<" "
#define nl cout<<endl
typedef long long LL;
const int N=100010;
int len;
int A[N],B[N],C[N];
int from[N];//begin[i] 记录比ai大的首个b的下标
LL sumCnt[N];//将0到i的cnt累加
void init(){
cin>>len;
ffor(i,0,len) scanf("%d",&A[i]);
ffor(i,0,len) scanf("%d",&B[i]);
ffor(i,0,len) scanf("%d",&C[i]);
sort(A,A+len);
sort(B,B+len);
sort(C,C+len);
int ci=0,bi=0;
while(ci<len&&bi<len){
if(C[ci]<=B[bi]){
ci++;
}else{
bi==0 ? sumCnt[bi]=len-ci : sumCnt[bi]+=sumCnt[bi-1]+len-ci;
bi++;
}
}
//考虑剩余的
while(bi<len){
sumCnt[bi]+=sumCnt[bi-1]+len-ci;
++bi;
}
int ai=len-1;
rfor(i,len-1,0){
if(A[ai]>=B[i]){
from[ai]=i+1;
ai--;
i++;
}
}
while(ai>-1) from[ai--]=0;
}
int main(){
init();
LL ans=0;
ffor(i,0,len){
ans+=sumCnt[len-1]-sumCnt[from[i]-1];
}
cout<<ans<<endl;
return 0;
}
460ms 原版
#include <iostream>
#include <cstdio>
#include<algorithm>
using namespace std;
#define ffor(i,a,b) for(int i=a;i<b;i++)
#define rfor(i,a,b) for(int i=a;i>=b;i--)
#define out(x) cout<<x<<" "
#define nl cout<<endl
typedef long long LL;
const int N=100010;
int len;
int A[N],B[N],C[N];
int from[N];//begin[i] 记录比ai大的首个b的下标
int cnt[N];//cnt[i]记录比bi大的C有多少个
LL sumCnt[N];//将0到i的cnt累加
void init(){
cin>>len;
ffor(i,0,len) scanf("%d",&A[i]);
ffor(i,0,len) scanf("%d",&B[i]);
ffor(i,0,len) scanf("%d",&C[i]);
sort(A,A+len);
sort(B,B+len);
sort(C,C+len);
//双指针
int count=0;
int bi=len-1;
rfor(i,len-1,0){
if(C[i]>B[bi]){
count++;
}else{
cnt[bi]=count+cnt[bi+1];
bi--;
count=0;
i++;//保留当前c
}
}
if(bi>=0){
cnt[bi]=count+cnt[bi+1];bi--;
}
while(bi>-1) cnt[bi--]=len;
/*
ffor(i,0,len){
out(B[i]);out(cnt[i]);
}
nl;
*/
sumCnt[0]=cnt[0];
ffor(i,1,len){
sumCnt[i]+=sumCnt[i-1]+cnt[i];
}
// 双指针
int ai=len-1;
rfor(i,len-1,0){
if(A[ai]>=B[i]){
from[ai]=i+1;
ai--;
i++;
}
}
while(ai>-1) from[ai--]=0;
/*
ffor(i,0,len){
out(A[i]);
out(from[i]);
}
nl;*/
}
int main(){
init();
LL ans=0;
ffor(i,0,len){
ans+=sumCnt[len-1]-sumCnt[from[i]-1];
}
cout<<ans<<endl;
return 0;
}