• Codeforces 1119D(差分)


    题面

    传送门

    分析

    先考虑(O(nk))的做法,先按s从小到大排序,每个串的数显然形成了n个连续区间([s_i+l,s_i+r]),且这些区间的左端点升序排列,然后把区间合并就可以知道有多少个不同的数了

    然后考虑优化

    对于s[i]产生的区间,我们考虑s[i]和s[i+1]产生的区间之间的间隔

    (s_i+r leq s_{i+1}+l),即(r-l leq s_{i+1}-s_i)

    ​ 则说明s[i]产生的区间和s[i+1]产生的区间不相交,答案增加((s_i+r)-(s_i+l)+1=r-l+1)

    否则说明(s_i+l)(s_{i+1}+l)被占满了,答案增加(s_{i+1}-s_i)

    定义差分(d_i=s_{i+1}-s_i)

    综上,我们要求(sum egin{cases} r-l+1,r-l leq d_i \ d_i,r-l > d_iend{cases})

    但是这样还是O(n)的,如何优化?

    我们发现这个式子与区间的顺序无关,因此我们按(d_i)排序,每次就可以二分找到小于(d_i)的区间的位置,然后前缀和就可以了

    注意我们刚刚讨论的都是前n-1个区间,最后一个区间直接加上他的长度就可以了

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 100005
    using namespace std;
    int n,m;
    long long s[maxn];
    long long d[maxn];
    struct node{
    	long long dif;
    	int id;
    	friend  bool operator < (node p,node q){
    		return p.dif<q.dif;
    	}
    }a[maxn];
    long long sumd[maxn];
    int bin_search(int l,int r,long long k){
    	int mid,ans=0;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(a[mid].dif<=k){
    			ans=mid;
    			l=mid+1;
    		}else r=mid-1;
    	}
    	return ans+1;
    }
    long long solve(long long l,long long r){
    	int pos=bin_search(1,n-1,r-l);
    	long long ans=0;
    	if(pos-1>0) ans+=sumd[pos-1];
    	if(pos<n){
    		ans+=(n-pos)*(r-l+1);
    	}
    	ans+=(r-l+1);
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%I64d",&s[i]);
    	sort(s+1,s+1+n);
    	for(int i=1;i<n;i++){
    		d[i]=s[i+1]-s[i];
    	}
    	for(int i=1;i<n;i++){
    		a[i].dif=d[i];
    		a[i].id=i;
    	}
    	sort(a+1,a+n);
    	for(int i=1;i<n;i++){
    		sumd[i]=sumd[i-1]+a[i].dif;
    	}
    	long long l,r;
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++){
    		scanf("%I64d %I64d",&l,&r);
    		printf("%I64d
    ",solve(l,r));
    	}
    }
    
    
  • 相关阅读:
    java&nbsp;split
    百度知道
    2014年10月27日
    2014年10月27日
    mybatis批量update,返回行数为-1
    mybatis批量插入:oracle和mysql的区别
    oracle数据库,mybatis批量insert,缺失values字段
    java后台接收json数据,报错com.alibaba.fastjson.JSONObject cannot be cast to xxx
    C++——运算符重载(上)
    C++——友元
  • 原文地址:https://www.cnblogs.com/birchtree/p/10663398.html
Copyright © 2020-2023  润新知