题目链接: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 ;
}
HDU-4638 Group 树状数组+离线的更多相关文章
-
HDU 4638 Group 树状数组 + 思路
实际上就是问这个区间编号连续的段的个数,假如一个编号连续的段有(a+b)个人,我把他们分在同一组能得到的分值为(a+b)^2,而把他们分成人数为a和b的两组的话,得到的分值就是a^2+b^2,显然(a ...
-
HDU 4638 Group ★(树状数组)
题意 询问一段区间里的数能组成多少段连续的数. 思路 先考虑从左往右一个数一个数添加,考虑当前添加了i - 1个数的答案是x,那么可以看出添加完i个数后的答案是根据a[i]-1和a[i]+1是否已经添 ...
-
Necklace HDU - 3874 (线段树/树状数组 + 离线处理)
Necklace HDU - 3874 Mery has a beautiful necklace. The necklace is made up of N magic balls. Each b ...
-
2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化
http://acm.hdu.edu.cn/showproblem.php?pid=5792 1012 World is Exploding 题意:选四个数,满足a<b and A[a]< ...
-
SPOJ DQUERY树状数组离线or主席树
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
-
D-query SPOJ 树状数组+离线
D-query SPOJ 树状数组+离线/莫队算法 题意 有一串正数,求一定区间中有多少个不同的数 解题思路--树状数组 说明一下,树状数组开始全部是零. 首先,我们存下所有需要查询的区间,然后根据右 ...
-
HDU 4638 Group (线段树 | 树状数组 + 离线处理)
Group Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
-
HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
-
HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)
题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...
随机推荐
-
在C#中读取枚举值的描述属性
枚举: public enum EnumLanugage { [System.ComponentModel.Description("中文")] Chinese, English ...
-
UART IP和UVM的验证平台
UART是工程师在开发调试时最常用的工具的,其通信协议简单.opencores 网站提供了兼容16550a的UART IP其基本特性如下: uart16550 is a 16550 compatibl ...
-
让delphi程序不受WINDOWS日期格式的影响
http://www.cnblogs.com/hnxxcxg/archive/2013/01/30/2882672.html 如果WINDOWS系统的短日期格式为“yyyy/m/d”,执行下面的代码会 ...
-
perl 登录某网站
<pre name="code" class="html">use Net::SMTP; use LWP::UserAgent; use HTTP: ...
-
DNS协议(一)
在互联网上要想与另外一台主机通信,要知道对方的IP地址,但是IP地址是很难记忆的, 比如百度的一台服务器的IP地址为115.239.210.27,我们在浏览器中输入http://115.239.210 ...
-
【Codeforces Round 1110】Codeforces Global Round 1
Codeforces Round 1110 这场比赛只做了\(A\).\(B\).\(C\),排名\(905\),不好. 主要的问题在\(D\)题上,有\(505\)人做出,但我没做出来. 考虑的时候 ...
-
HeadFirst Ruby 第十四章总结 Web apps: Serving HTML
前言 这一章节主要讲了如何利用 Ruby 中的 Sinatra 这个 gem 来创建一个 Web app 的具体流程,其中的要点包括了: Sinatra, a third party library ...
-
ubuntu下安装vmTools, 和共享文件
如果没有需要下载一个vmTools,我是下载的 然后加载到光驱,然后在ubuntu下面可以找到光驱 解压里面的文件, 我解压到 Documents下面 然后ctrl + alt + t进入控制台 cd ...
-
Java实现匿名内部类的简单应用
在查看数码相片时,通常会使用一款图片查看软件,该软件应该能遍历文件夹下的所有图片并进行显示.编写程序,实现一个图片查看软件,它可以支持6张图片,通过单击不同的按钮就可以查看不同的图片. 思路分析:就是 ...
-
package &#39;orocos-bfl&#39; not found CMake Error at /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake:283 (message):
#没有数字 sudo apt-get install ros-indigo-bfl