\[ \texttt{Description} \]
给两个长度为 \(n\) 的序列 \(a\) 和 \(b\) ,求满足 \(a_i+a_j>b_i+b_j \ (i<j)\) 的数对个数。
\[
\texttt{Solution}
\]
\[ \texttt{Code} \]
#include<cstdio>
#define RI register int
using namespace std;
namespace IO
{
static char buf[1<<20],*fs,*ft;
inline char gc()
{
if(fs==ft)
{
ft=(fs=buf)+fread(buf,1,1<<20,stdin);
if(fs==ft)return EOF;
}
return *fs++;
}
#define gc() getchar()
inline int read()
{
int x=0,f=1;char s=gc();
while(s<'0'||s>'9'){if(s=='-')f=-f;s=gc();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=gc();}
return x*f;
}
}using IO::read;
const int N=200100,MLOGN=10001000;
int n;
int a[N],b[N];
const int INF=2e9;
int tot,root;
struct SegmentTree{
int lc,rc;
int cnt;
}t[MLOGN];
int New()
{
tot++;
t[tot].lc=t[tot].rc=t[tot].cnt=0;
return tot;
}
void insert(int &p,int l,int r,int delta,int val)
{
if(!p)
p=New();
t[p].cnt+=val;
if(l==r)return;
int mid=(long long)(l+r)>>1;
if(delta<=mid)
insert(t[p].lc,l,mid,delta,val);
else
insert(t[p].rc,mid+1,r,delta,val);
}
int ask(int p,int l,int r,int s,int e)
{
if(!p)
return 0;
if(s<=l&&r<=e)
return t[p].cnt;
int mid=(long long)(l+r)>>1;
int val=0;
if(s<=mid)
val+=ask(t[p].lc,l,mid,s,e);
if(mid<e)
val+=ask(t[p].rc,mid+1,r,s,e);
return val;
}
long long ans;
int main()
{
n=read();
for(RI i=1;i<=n;i++)
a[i]=read();
for(RI i=1;i<=n;i++)
b[i]=read();
for(RI i=n;i>=1;i--)
{
ans+=ask(root,-INF,INF,-INF,a[i]-b[i]-1);
insert(root,-INF,INF,b[i]-a[i],1);
}
printf("%lld\n",ans);
return 0;
}
\[ \texttt{Thanks} \ \texttt{for} \ \texttt{watching} \]
原文:https://www.cnblogs.com/cjtcalc/p/12484127.html