hdu6701 Make Rounddog Happy

Posted by wing_zero on Thu, 03 Oct 2019 01:43:10 +0200

[Title Description]

Conveyor belt
Let max(al,al+1,... The Number of Intervals of, ar-(r-l+1)<=k

[thinking]

Divide and conquer
Preprocessing each number is smaller than it and unequal to each other's leftmost and rightmost ends
Find the number of intervals across this number (enumerated by the shorter length)
There are two ways of preprocessing, RMQ multiplier or monotone stack maintenance.
Unequal among them can be realized by lst arrays
There are also two forms of divide-and-conquer, ordinary divide-and-conquer or heuristic divide-and-conquer.
I use monotonous stack + common divide and conquer
RMQ + Heuristic Divide and Conquer Visible on this blog Conveyor belt

[Code]

#include <iostream>
#include <string.h>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
#define loop(i, x) for(int i = 0; i < x; ++i)
#define circle(i, st, en) for(int i = st; i <= en; ++i)
#define reverse(i, st, en) for(int i = st; i >= en; --i)
#define wh(t) while(t--)
#define mem(i, x) memset(i, x, sizeof(i))
#define ssc(x) scanf("%s", s)
#define dsc(x) scanf("%lld", &x)
#define lfsc(x) scanf("%lf", &x)
typedef long long ll;
const int MAXN=3e5+10;
const ll P=1e9+7;
const double eps=1e-10;
const double pi=acos(-1.0);
const int INF=0x3f3f3f3f;
int T;
int n,k;
int f[MAXN];
int a[MAXN];
int llst[MAXN];
int rlst[MAXN];
int pre[MAXN];
int lpos[MAXN];
int rpos[MAXN];
struct node{
	int num;
	int pos;
	node(){}node(int num_,int pos_){num=num_;pos=pos_;}
};
stack<node> s;
ll solve(int l,int r){
	if(l<=r) return r-l+1;
	return 0;
}
ll dfs(int l,int r){
	if(l>r) return 0;
	int mid=(l+r)>>1;
	ll res=0;
	int lim=max(a[mid]-k,1);
	if(mid-lpos[mid]>rpos[mid]-mid){
		reverse(i,rpos[mid],mid)
			res+=solve(max(llst[i],lpos[mid]),min(mid,i-lim+1));
	}
	else{
		circle(i,lpos[mid],mid)
			res+=solve(max(mid,i+lim-1),min(rlst[i],rpos[mid]));
	}
	res+=dfs(l,mid-1);
	res+=dfs(mid+1,r);
	return res;
}
int main(){
	scanf("%d",&T);
	wh(T){
		scanf("%d%d",&n,&k);
		while(!s.empty()) s.pop();
		loop(i,MAXN) pre[i]=0;
		circle(i,1,n){
		    scanf("%d",&a[i]);
		    llst[i]=pre[a[i]]+1,pre[a[i]]=i;
		}
		circle(i,1,n){
			int pos=i;
			llst[i]=max(llst[i],llst[i-1]);
		    while(!s.empty()&&s.top().num<=a[i]){
			    pos=s.top().pos;
				s.pop();	
			} 
			s.push(node(a[i],pos));
			lpos[i]=max(pos,llst[i]);
		}
		while(!s.empty()) s.pop();
		loop(i,MAXN) pre[i]=n+1;
		reverse(i,n,1) rlst[i]=pre[a[i]]-1,pre[a[i]]=i;
		rlst[n+1]=n+1;
		reverse(i,n,1){
			int pos=i;
			rlst[i]=min(rlst[i],rlst[i+1]);
			while(!s.empty()&&s.top().num<=a[i]){
				pos=s.top().pos;
				s.pop();
			}
			s.push(node(a[i],pos));
			rpos[i]=min(pos,rlst[i]);
		}
		printf("%lld\n",dfs(1,n));
	}
	return 0;
}