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 }

 

posted @ 2015-09-11 16:02  miao_a_miao  阅读(161)  评论(0编辑  收藏  举报