标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4638
1 5 2 3 1 2 5 4 1 5 2 4
1 2
/**
hdu 4368 树状数组
题目大意:给定1~n的一个排列,每次查询一个区间(l,r),将所求区间内的数进行分组,每一组内的数的值必须是连着的,该组的价值为元素个数的平方和
问在区间价值最大的情况下,要分成几组
解题思路:用树状数组离线维护,把询问按照右区间递增排序,然后从1~n维护,维护到i时注意找寻前i个是不是有a[i]-1,和a[i]+1,有的话直接去掉,因为
这两个数必定要和a[i]分到一组,留一个就好了
*/
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
using namespace std;
const int maxn=100100;
int n,m,a[maxn],p[maxn],ans[maxn];
struct note
{
int l,r,id;
bool operator < (const note &other)const
{
return r<other.r;
}
}que[maxn];
int c[maxn];
int lowbit(int x)
{
return x&(-x);
}
int sum(int x)
{
int ret=0;
while(x>0)
{
ret+=c[x];x-=lowbit(x);
}
return ret;
}
void add(int x,int d)
{
while(x<=n)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
p[a[i]]=i;
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&que[i].l,&que[i].r);
que[i].id=i;
}
sort(que,que+m);
memset(c,0,sizeof(c));
int j=0;
for(int i=1;i<=n;i++)
{
add(i,1);
if(a[i]>1&&p[a[i]-1]<i)add(p[a[i]-1],-1);
if(a[i]<n&&p[a[i]+1]<i)add(p[a[i]+1],-1);
while(j<m&&que[j].r==i)
{
ans[que[j].id]=sum(que[j].r)-sum(que[j].l-1);
j++;
}
}
for(int i=0;i<m;i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/48086555