HDU-4638 Group 树状数组+离线

  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4638

  个人认为比较不错的题目。

  题意:给一个1-n的排列,询问区间[l,r]的数排序后连续区间的个数。

  对于这种题目容易想到对询问离线处理,难点是怎样在logn的时间内求出连续区间的个数。先对询问按右端点y从左到右排序,然后从左到右扫描整个数列,现在考虑加一个数num进去,如果我们前面存在num-1或者num+1,那么数列连续区间的个数是没有增加的,可能还会减少。因此我们可以维护一个数组数组或者线段树,对于每加进去的一个数num[i],对 i 点加1,如果 i 点前存在num[i]-1和num[i]+1,那么分别对他们所在的点-1。如果遇到询问,就求和就可以了。。。

 //STATUS:C++_AC_484MS_3364KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=;
const int INF=0x3f3f3f3f;
const int MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End struct Node{
int x,y,id;
bool operator <(const Node& a)const {
return y<a.y;
}
}nod[N]; int num[N],sum[N],ans[N],vis[N],w[N];
int T,n,m; int lowbit(int x)
{
return x&(-x);
} void update(int x,int val)
{
while(x<=n){
sum[x]+=val;
x+=lowbit(x);
}
} int getsum(int x)
{
int ret=;
while(x){
ret+=sum[x];
x-=lowbit(x);
}
return ret;
} int main(){
// freopen("in.txt","r",stdin);
int i,j,k;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=;i<=n;i++){
scanf("%d",&num[i]);
w[num[i]]=i;
}
for(i=;i<m;i++){
scanf("%d%d",&nod[i].x,&nod[i].y);
nod[i].id=i;
}
sort(nod,nod+m);
mem(sum,);mem(vis,);
for(i=,k=;i<=n;i++){
update(i,);
if(vis[num[i]-])update(w[num[i]-],-);
if(vis[num[i]+])update(w[num[i]+],-);
vis[num[i]]=;
for(;nod[k].y==i && k<m;k++){
ans[nod[k].id]=getsum(nod[k].y)-getsum(nod[k].x-);
}
if(k==m)break;
} for(i=;i<m;i++){
printf("%d\n",ans[i]);
}
}
return ;
}
上一篇:nginx服务器是怎么执行php脚本的?


下一篇:[译]Stairway to Integration Services Level 12 - 高级日志配置