标签:
2 4 2 3 1 2 4 10 5 0 3 4 5 2 1 6 7 8 9
5 28HintFirst Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3]
rmq+二分
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
#define eps 1e-8
typedef __int64 ll;
const int mod=1e9+7;
using namespace std;
#define N 100007
int a[N],n;
int dpmin[N][25],dpmax[N][25];
int k;
inline bool judge(int le,int ri)
{
int kk=log2((ri-le+1)*1.0);
int mi=min(dpmin[le][kk],dpmin[ri-(1<<kk)+1][kk]);
int ma=max(dpmax[le][kk],dpmax[ri-(1<<kk)+1][kk]);
return ma-mi<k;
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
dpmin[i][0]=dpmax[i][0]=a[i];
for(j=1;(1<<j)<=n;j++)
for(i=1;i+(1<<j)-1<=n;i++)
{
int p=1<<(j-1);
dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+p][j-1]);
dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+p][j-1]);
}
__int64 ans=0;
int le,ri,p;
for(i=1;i<=n;i++)
{
le=i;
ri=n;
while(le<=ri)
{
int mid=(le+ri)>>1;
if(judge(i,mid))
{
p=mid;
le=mid+1;
}
else
ri=mid-1;
}
ans+=p-i+1;
}
printf("%I64d\n",ans);
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
#define eps 1e-8
using namespace std;
const int mod=1e9+7;
#define INF 0x3f3f3f3f
const int N=100005;
int mique[N],maque[N],mihead,mahead,mitail,matail;
int n,a[N],k;
int pre,now;
__int64 ans;
inline void miinque(int i)
{
while(mihead<mitail&&a[i]<a[mique[mitail-1]]) mitail--;
mique[mitail++]=i;
}
inline void mainque(int i)
{
while(mahead<matail&&a[i]>a[maque[matail-1]]) matail--;
maque[matail++]=i;
}
void outque(int pos)
{
if(a[maque[mahead]]-a[mique[mihead]]>=k)
{
int nowlen=pos-now-1;
int prelen=pre-now;
ans+=(__int64)(nowlen+1)*nowlen/2;
if(prelen>=1)
ans-=(__int64)(prelen+1)*prelen/2;
pre=pos-1;
}
while(a[maque[mahead]]-a[mique[mihead]]>=k)
if(mique[mihead]<maque[mahead])
{
now=mique[mihead]+1;
mihead++;
}
else
{
now=maque[mahead]+1;
mahead++;
}
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
mihead=mahead=mitail=matail=0;
pre=now=1;
ans=0;
for(i=1;i<=n;i++)
{
miinque(i);
mainque(i);
outque(i);
}
if(pre<n)
{
int nowlen=n-now;
int prelen=pre-now;
ans+=(__int64)(nowlen+1)*(nowlen)/2;
if(prelen>=1)
ans-=(__int64)(prelen+1)*(prelen)/2;
pre=n-1;
}
printf("%I64d\n",ans+n);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 5089 Assignment(rmq+二分 或 单调队列)
标签:
原文地址:http://blog.csdn.net/u014737310/article/details/46998227