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; }