标签:
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