1. 程式人生 > >2015 Multi-University Training Contest 1 /hdu 5289 Assignment -樹狀陣列

2015 Multi-University Training Contest 1 /hdu 5289 Assignment -樹狀陣列

點選開啟題目連結http://acm.hdu.edu.cn/showproblem.php?pid=5289

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100100
#define lowbit(i) (i&(-i))
int tree1[MAXN],tree2[MAXN];

//int max(int a,int b)
//{
//	return a>b?a:b;
//}
//int min(int a,int b)
//{
//	return a<b?a:b;
//}
// 
//int lowbit(int i)
//{
//	return i&(-i);
//}
void addmin(int i,int num)
{
	while(i<MAXN)
	{
		tree1[i]=min(tree1[i],num);
		i+=lowbit(i);
	}
}
int querymin (int i)
{
	int sum=MAXN;
	while(i)
	{
		sum=min(sum,tree1[i]);
		i-=lowbit(i);
	}
	return sum;
}

void addmax(int i,int num)
{
	while(i<MAXN)
	{
		tree2[i]=max(tree2[i],num);
		i+=lowbit(i);
	}
}
int querymax(int i)
{
	int sum=0;
	while(i)
	{
		sum=max(sum,tree2[i]);
		i-=lowbit(i);
	}
	return sum;
}

int main()
{
	int num[MAXN];
	int T,n,k;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d",&n,&k);
		memset(num,0,sizeof(num));
		memset(tree1,MAXN,sizeof(tree1));
		memset(tree2,0,sizeof(tree2));
		
		for(int i=1;i<=n;i++) 
		{
			scanf("%d",&num[i]);
		}
		
		long long ans=0; //竟然忽略了這個, WAWAWAWAWAWWA 
		for(int i=n;i>0;i--)
		{
			addmin(i,num[i]);
			addmax(i,num[i]);
			int low=i;
			int high=n;
			while(low<=high)
			{
				int mid= (low+high)/2;
				int ma=querymax(mid);
				int mi=querymin(mid);
				if(ma-mi>=k)
				{
					high=mid-1;
				}
				else
				{
					low=mid+1;
				}
			}
			ans+=(low-i);  //low是當前右邊界,i是當前左邊界 
		}
		printf("%lld\n",ans);
	}
	return 0;
}