**1.區間是一段的,不是斷開的喲**
**2.代碼是看著標程寫的**
**3.枚舉左端點,二分右端點流程:**

~~~
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=200007;
int minn[N][20];//2^18=262144 2^20=1048576
int maxx[N][20];
//----------------------查詢O(1)-------------
int queryMin(int l,int r)
{
int k=floor(log2((double)(r-l+1)));//2^k <= (r - l + 1),floor()向下取整函數
return Min(minn[l][k],minn[r-(1<<k)+1][k]);
}
int queryMax(int l,int r)
{
int k=floor(log2((double)(r-l+1)));
return Max(maxx[l][k],maxx[r-(1<<k)+1][k]);
}
//-------------------------------------------------
int calc(int l,int r)
{
int k=log2((double)(r-l+1));
int MAX=Max(maxx[l][k],maxx[r-(1<<k)+1][k]);
int MIN=Min(minn[l][k],minn[r-(1<<k)+1][k]);
return MAX-MIN;
}
int main()
{
int T;
int n,k,i,j,p;
LL ans;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(i=1; i<=n; ++i)
{
scanf("%d",&j);
minn[i][0]=maxx[i][0]=j;
}
//------------------------------------------預處理O(nlogn)---------------
for(j=1; (1<<j)<=n; ++j)//1<<j==2^j,枚舉區間長度1,2,4,8,16,,,,,
for(i=1; i+(1<<j)-1<=n; ++i)//i+(1<<j)-1表示區間右邊界,枚舉區間左邊界
{
p=(1<<(j-1));
minn[i][j]=Min(minn[i][j-1],minn[i+p][j-1]);
maxx[i][j]=Max(maxx[i][j-1],maxx[i+p][j-1]);
}
//-----------------------------------------------------------------------
//---------------------------枚舉左端點,二分右端點---------------------------
int l,r,mid;
ans=0;
//左端點固定為i,右端點用l,r,mid去確定,最后用l和r中的其中一個,此時l+1==r
for(i=1; i<=n; ++i)
{
l=i,r=n;
while(l+1<r)
{
mid=(l+r)>>1;//(l+r)/2==(l+r)>>1
if(calc(i,mid)<k)
{
l=mid;
}
else
{
r=mid-1;//自己去演示算法流程就知道r可以賦值mid-1
}
}
if(calc(i,r)<k)
{
ans=ans+(LL)(r-i+1);
}
else
{
ans=ans+(LL)(l-i+1);
}
}
//---------------------------------------------------------------------------
printf("%lld\n",ans);
}
return 0;
}
~~~
- 前言
- The 12th Zhejiang Provincial Collegiate Programming Contest - D
- 用鄰接表存儲n個頂點m條弧的有向圖
- hdu 5289 Assignment(給一個數組,求有多少個區間,滿足區間內的最大值和最小值之差小于k)
- hdu 1358 Period(給定一個字符串,求有多少個前綴(包括自己本身),它是由k(k&gt;2,并且盡量大)個循環節組成的)
- hdu 1806 Frequent values(給定一個非降序數組,求任意區間內出現次數最多的數的次數)
- poj 3264 Balanced Lineup(查詢區間最大值與最小值的差)
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
- HDU 1015 Safecracker(第一次用了搜索去遍歷超時,第二次用for循環可以了,思路一樣的)
- HDU 1016 Prime Ring Problem(DFS)
- HDU 1026 Ignatius and the Princess I(BFS+記錄路徑)
- HDU 1072 Nightmare(BFS)
- HDU 1237 簡單計算器(后綴式+棧)