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