码迷,mamicode.com
首页 > 其他好文 > 详细

cf1119d Frets On Fire 前缀和+二分

时间:2019-11-03 01:07:59      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:查找   names   图片   长度   不同   src   mic   一个   i++   

题目:http://codeforces.com/problemset/problem/1119/D

题意:给一个数n,给出n个数组的第一个数(a[0]=m,a[1]=m+1,a[2]=m+2,...,a[n]=m+n),给定q个查询,每个查询问所有数组的[l,r]区间内总共出现了多少个不同的数。

思路:答案与给出查询的区间无关,只与区间长度有关。

 

两数组不重复的数与数组第一个数的差、区间长度有关。两数组内不重复的数为min(两数组a[0]之差,区间长度)。

因此对数组第一个数进行sort,之和求出数组第一位之差delta[],再按照升序排序,小于区间长度的都取delta[],大于区间长度的都取len。

然后对delta求一下前缀和sum,查找的时候对delta进行二分。

技术图片

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
long long s[maxn]={0},delta[maxn]={0},sum[maxn]={0}; 
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%lld",&s[i]);
    sort(s,s+n);
    for(int i=0;i<n-1;i++)delta[i]=s[i+1]-s[i];
    sort(delta,delta+n-1);
    for(int i=0;i<n;i++)
    {
        sum[i+1]=sum[i]+delta[i];
    }
    
    int q;
    scanf("%d",&q);
    for(int i=0;i<q;i++)
    {
        long long l,r,len,ans=0;
        scanf("%lld%lld",&l,&r);
        len=r-l+1;
        int p=upper_bound(delta,delta+n-1,len)-delta;
        ans=sum[p]+len*(n-p);
        if(i!=q-1)printf("%lld ",ans);
        else printf("%lld\n",ans);
    }
    return 0; 
} 

 

cf1119d Frets On Fire 前缀和+二分

标签:查找   names   图片   长度   不同   src   mic   一个   i++   

原文地址:https://www.cnblogs.com/myrtle/p/11784826.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!