zoukankan      html  css  js  c++  java
  • 题解【CF1324D Pair of Topics】

    [ exttt{Description} ]

    给两个长度为 (n) 的序列 (a)(b) ,求满足 (a_i+a_j>b_i+b_j (i<j)) 的数对个数。

    [ exttt{Solution} ]

    • 首先注意到这个式子左右两边同时出现了 (i,j) ,也就是说式子两边不是互相独立的。

    • 嗯,自然地想到了移项大法,式子可以化为 (a_i-b_i>b_j-a_j (i<j)) 。式子的一边为 (i) ,一边为 (j) ,就使得式子两边互相独立。

    • 我们发现这个偏序问题简直不要太好做,有很多的方法可以解决这个偏序问题,这里介绍一种 动态开点权值线段树 的做法。

    • 倒序扫描,从 (n) 扫到 (1)

      1. 将权值线段树中值域在 ([-inf,a_i-b_i-1]) 的数的个数计入答案中。
      2. 在权值线段树中令 (b_i-a_i) 的个数加一。
    • 时间复杂度 (mathcal{O(n log n)}) ,空间复杂度 (O(n log size)) ,如果离散化一下可以做到 (O(n log n))

    [ exttt{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
    ",ans);
    
    	return 0;
    }
    

    [ exttt{Thanks} exttt{for} exttt{watching} ]

  • 相关阅读:
    logback-spring.xml配置文件详解
    SpringBoot-Controller接收参数的几种常用方式
    spring boot配置定时任务设置
    SpringCloud 配置文件 application.yml和 bootstrap.yml区别
    ajax/get请求
    ajax封装2
    ajax封装1
    楼层特效
    旋转动画
    联动动画
  • 原文地址:https://www.cnblogs.com/cjtcalc/p/12484127.html
Copyright © 2011-2022 走看看