hdu 5720 BestCoder 2nd Anniversary Wool 推理+一维区间的并

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5720

题意:有n(n <= 105)个数 ,每个数小于等于 1018;问在给定的[L,R]区间中,有多少个数不能与已知的n个数中的任何两个组成三角形?

思路:由三角形的边长关系移位即可得到符合关系的长度len:a[i] - a[j] +1 <= len <= a[i] + a[j] - 1;(a[i] > a[j])

易知当i固定时,j为i - 1时len符合的区间是最大的;

这就变成了O(n)的算法,求出每个区间的并即可;

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define A first
#define B second
#define MK make_pair
#define esp 1e-8
#define zero(x) (((x)>0?(x):-(x))<eps)
#define bitnum(a) __builtin_popcount(a)
#define clear0 (0xFFFFFFFE)
#define mod 1000000007
typedef long long ll;
typedef pair<ll,ll> PLL;
typedef unsigned long long ull;
template<typename T>
void read1(T &m)
{
    T x = 0,f = 1;char ch = getchar();
    while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
    while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
    m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
    if(a>9) out(a/10);
    putchar(a%10+'0');
}
inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
const int maxn = 1e5+10;
ll a[maxn];
PLL p[maxn];
int main()
{
    //freopen("data.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int T, kase = 1;
    scanf("%d",&T);
    while(T--){
        ll n, L, R;
        read3(n,L,R);
        rep1(i,1,n){
            read1(a[i]);
        }
        sort(a+1,a+1+n);
        int cnt = 0;
        rep1(i,2,n){
            p[cnt].A = a[i] - a[i-1] + 1;
            p[cnt++].B = a[i] + a[i-1] - 1;
        }
        sort(p,p+cnt);
        ll ans = R - L + 1;
        rep0(i,0,cnt){
            ll first = p[i].A, last = p[i].B;
            if(first > R) break;
            while(p[i+1].A <= last)
                last = max(last, p[++i].B);
            if(last < L) continue;
            first = max(L,first), last = min(last,R);
            ans -= last - first + 1;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

 

posted @ 2016-07-24 22:26  hxer  阅读(277)  评论(0编辑  收藏  举报