hdu 5289 rmp+二分+枚举后界 or单调队列 ****
好题~~
给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数,枚举后界~~
又是一种没见过的方法,太弱了/(ㄒoㄒ)/~~
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <iostream> 6 #include <queue> 7 #include <algorithm> 8 #include <vector> 9 #include <set> 10 using namespace std; 11 #define LL __int64 12 #define INF 0x3f3f3f3f 13 const int MAXN=100005; 14 #define mod 1000000007 15 16 int a[MAXN]; 17 LL ans; 18 int dp1[MAXN][30],dp2[MAXN][30]; 19 20 void init(int n) 21 { 22 for(int i=1;i<=n;i++) 23 dp1[i][0]=dp2[i][0]=a[i]; 24 for(int j=1;(1<<j)<=n;j++) 25 { 26 for(int i=1;i+(1<<j)-1<=n;i++) 27 { 28 dp1[i][j]=max(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]); 29 dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]); 30 } 31 } 32 } 33 34 int RMQ(int L,int R) 35 { 36 int k=0; 37 while((1<<(k+1))<=R-L+1)k++; 38 return max(dp1[L][k],dp1[R-(1<<k)+1][k])-min(dp2[L][k],dp2[R-(1<<k)+1][k]); 39 } 40 41 int binarySearch(int L,int R,int n,int k) 42 { 43 int mid; 44 int l=L,r=R; 45 while(l<=r) 46 { 47 mid=(l+r)/2; 48 if(RMQ(mid,R)>=k) 49 { 50 l=mid+1; 51 } 52 else 53 { 54 r=mid-1; 55 } 56 } 57 if(RMQ(mid,R)>=k) 58 mid++; 59 return mid; 60 } 61 int main() 62 { 63 int T,i,j,n,k,mi,ma,l,r; 64 while(~scanf("%d",&T)) 65 { 66 while(T--) 67 { 68 scanf("%d%d",&n,&k); 69 for(i=1;i<=n;i++) 70 scanf("%d",&a[i]); 71 if(!k) 72 { 73 printf("0\n"); 74 continue; 75 } 76 if(k==1) 77 { 78 printf("%d\n",n); 79 continue; 80 } 81 init(n); 82 ans=0; 83 for(i=j=1;i<=n;i++) 84 { 85 j=binarySearch(j,i,n,k); 86 ans+=i-j+1; 87 } 88 printf("%I64d\n",ans); 89 } 90 } 91 return 0; 92 }
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std ; 6 #define LL __int64 7 deque <LL> deq1 , deq2 ; 8 //单调队列,deq1最大值,deq2最小值 9 LL a[100010] ; 10 int main() { 11 int t , n , i , j ; 12 LL k , ans ; 13 #ifndef ONLINE_JUDGE 14 freopen("1.in","r",stdin); 15 #endif 16 scanf("%d", &t) ; 17 while( t-- ) { 18 scanf("%d %I64d", &n, &k) ; 19 for(i = 0 ; i < n ; i++) 20 scanf("%I64d", &a[i]) ; 21 if(k == 0) { 22 printf("0\n") ; 23 continue ; 24 } 25 while( !deq1.empty() ) deq1.pop_back() ; 26 while( !deq2.empty() ) deq2.pop_back() ; 27 for(i = 0 , j = 0 , ans = 0; i < n ; i++) {//i在前,j在后 28 while( !deq1.empty() && deq1.back() < a[i] ) deq1.pop_back() ; 29 deq1.push_back(a[i]) ; 30 while( !deq2.empty() && deq2.back() > a[i] ) deq2.pop_back() ; 31 deq2.push_back(a[i]) ; 32 while( !deq1.empty() && !deq2.empty() && deq1.front() - deq2.front() >= k ) { 33 ans += (i-j) ; 34 //printf("%d %d,%I64d %I64d\n", i , j, deq1.front() , deq2.front() ) ; 35 if( deq1.front() == a[j] ) deq1.pop_front() ; 36 if( deq2.front() == a[j] ) deq2.pop_front() ; 37 j++ ; 38 } 39 } 40 while( j < n ) { 41 ans += (i-j) ; 42 j++ ; 43 } 44 printf("%I64d\n", ans) ; 45 } 46 return 0 ; 47 }