题意:

给定一个长度为n的数组,有m次的查询,每次查询[a,b]区间里比H小的数有多少个?

由于n和m的取值范围为0到10的5次方,所以直接回答会超时,所以考虑先读入所有的查询操作,然后依次回答比H小的[a,b]区间里的数有多少个,

求和类似于求正序数的方法。

写法可以边插变查,也可以边查边插,边查边插简单些;

可是这道题从头wa到了尾,原因是add函数少打了等于号,扇自己一巴掌.

边插边查:

#include <iostream>
#include <cstdio>
#include <time.h>
#include <stdlib.h>
#include <cstring>
#include<algorithm>
#define maxn 110000
#define LL int
using namespace std;
struct node
{
LL value,id;
};
struct querynode
{
LL L,R,H=-,cnt;
};
node a[maxn];
querynode que[maxn];
LL c[maxn];
LL N,M;
LL ans[maxn];
void init()
{
memset(a,,sizeof(a));
memset(c,,sizeof(c));
memset(ans,,sizeof(ans));
} bool cmp1(node a,node b)
{
return a.value<b.value;
}
bool cmp2(querynode a,querynode b)
{
return a.H<b.H;
}
int inline lowbit(int x){
return x & (-x);
}
void inline add(int x){
while(x <= N){
c[x]++;
x += lowbit(x);
}
}
int inline sum(int x){
int s = ;
while(x > ){
s += c[x];
x -= lowbit(x);
}
return s;
} void solve()
{
int t=;
for(int i=;i<=N;i++)
{
if(que[t].H==-)
{
break;
}
while(que[t].H<a[i].value && que[t].H!=-)
{
ans[ que[t].cnt ]=sum(que[t].R)-sum(que[t].L-);
t++;
}
add(a[i].id);
while(a[i].value==a[i+].value && i<=N)
{
i++;
add(a[i].id);
}
while(que[t].H==a[i].value && que[t].H!=-)
{
ans[ que[t].cnt ]=sum(que[t].R)-sum(que[t].L-);
t++;
}
}
for(int i=t;i<=M;i++)
{
ans[que[i].cnt]=sum(que[i].R)-sum(que[i].L-);
}
}
int main()
{
// freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
int Case=;
for(int Case=;Case<=t;Case++)
{
scanf("%d%d",&N,&M);
init();
for(int i=;i<=N;i++)
{
scanf("%d",&a[i].value);
a[i].id=i;
}
for(int i=;i<=M;i++)
{
scanf("%d%d%d",&que[i].L,&que[i].R,&que[i].H);
que[i].L++;
que[i].R++;
que[i].cnt=i;
}
sort(a+,a+N+,cmp1);
sort(que+,que+M+,cmp2);
solve();
printf("Case %d:\n",Case);
for(int i = ; i <= M; ++i){
printf("%d\n",ans[i]);
}
} return ;
}

边查边插:

#include <iostream>
#include <cstdio>
#include <time.h>
#include <stdlib.h>
#include <cstring>
#include<algorithm>
#define maxn 110000
#define LL int
using namespace std;
struct node
{
LL value,id;
};
struct querynode
{
LL L,R,H,cnt;
};
node a[maxn];
querynode que[maxn];
LL c[maxn];
LL N,M;
LL ans[maxn];
void init()
{
memset(a,,sizeof(a));
memset(c,,sizeof(c));
memset(ans,,sizeof(ans));
for(int i=;i<maxn;i++)
{
que[i].H=-;
}
} bool cmp1(node a,node b)
{
return a.value<b.value;
}
bool cmp2(querynode a,querynode b)
{
return a.H<b.H;
}
int inline lowbit(int x){
return x & (-x);
}
void inline add(int x){
while(x <= N ){
c[x]++;
x += lowbit(x);
}
}
int inline sum(int x){
int s = ;
while(x > ){
s += c[x];
x -= lowbit(x);
}
return s;
} void solve1()
{
for(int aski = ,ditj = ; aski < M; ++aski){
while(ditj < N && que[aski].H >= a[ditj].value){
add(a[ditj].id);
ditj++;
}
ans[que[aski].cnt] = sum(que[aski].R) - sum(que[aski].L - );
}
}
int main()
{
//freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
int Case=;
for(int Case=;Case<=t;Case++)
{
scanf("%d%d",&N,&M);
init();
for(int i=;i<N;i++)
{
scanf("%d",&a[i].value);
a[i].id=i+;
}
for(int i=;i<M;i++)
{
scanf("%d%d%d",&que[i].L,&que[i].R,&que[i].H);
que[i].L++;
que[i].R++;
que[i].cnt=i+;
}
sort(a,a+N,cmp1);
sort(que,que+M,cmp2);
solve1();
printf("Case %d:\n",Case);
for(int i = ; i <= M; ++i){
printf("%d\n",ans[i]);
}
} return ;
}

hdu4417(离线操作 + 树状数组)的更多相关文章

  1. HDU3874Necklace(树状数组+离线操作)

    此题的大意思说有一串珠子,每个珠子都有自己的欣赏值value,现在给你一串珠子每个的欣赏值,并给出一些询问,查询某个区间内部总欣赏值是多少,但是有一个约定就是如果这个区间内部有两个珠子的欣赏值是一样的 ...

  2. HDU---4417Super Mario 树状数组 离线操作

    题意:给定 n个数,查询 位置L R内 小于x的数有多少个. 对于某一次查询 把所有比x小的数 ”的位置“ 都加入到树状数组中,然后sum(R)-sum(L-1)就是答案,q次查询就要离线操作了,按高 ...

  3. Necklace(树状数组+离线操作)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 Necklace Time Limit: 15000/5000 MS (Java/Others) ...

  4. HDU 4630 No Pain No Game 树状数组+离线操作

    题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值. 解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数. ...

  5. Codeforces 369E Valera and Queries --树状数组+离线操作

    题意:给一些线段,然后给m个查询,每次查询都给出一些点,问有多少条线段包含这个点集中的一个或多个点 解法:直接离线以点为基准和以线段为基准都不好处理,“正难则反”,我们试着求有多少线段是不包含某个查询 ...

  6. bzoj 1878 SDOI2009树状数组 离线操作

    本来想写2120的,结果想起来了这个 我们先对于询问左端点排序,用树状数组存区间字母个数,对于每种字母, 第一次出现的位置记录为1,剩下的记录为0,然后记录下,每种颜色 后面第一个和他相同颜色的位置 ...

  7. ACM学习历程—HDU4417 Super Mario(树状数组 && 离线)

    Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...

  8. hdu-4417 Super Mario(树状数组 + 划分树)

    题目链接: Super Mario Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Other ...

  9. hdu 3333(树状数组 + 离线操作)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. Vim增强工具设置

    Vim增强工具设置操作准备:vim ~/.vimrc11. 缩进 & 制表符使 Vim 在创建新行的时候使用与上一行同样的缩进: set autoindent 2. 设置文件里的制表符 (TA ...

  2. BZOJ1744: [Usaco2005 oct]Skiing 奶牛滑雪

    n<=100 * m<=100的地图,每个数绝对值不超过25,从1,1到n,m,一开始速度v,从数字A走到数字B速度会变成v*2^(A-B),求到终点最短时间. 可以发现,相同的数字出发的 ...

  3. Codeforces 848C (cdq分治)

    Codeforces 848C Goodbye Souvenir Problem : 给一个长度为n的序列,有q个询问.一种询问是修改某个位置的数,另一种询问是询问一段区间,对于每一种值出现的最右端点 ...

  4. python学习之-- redis模块操作 集合和有序集合

    redis 模块操作之 集合set和有序集合zset Set 集合操作,不允许重复的列表sadd(name,value):name对应的集合中添加元素scard(name):获取name对应的集合中元 ...

  5. [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4108  Solved: 2195[Submit][Statu ...

  6. 学习日常笔记<day11>cookie及session

    1.会话管理 1.1会话管理定义 会话管理:管理浏览器客户端和服务端之间的会话过程中产生的会话数据 域对象:实现资源之间的数据共享 request 域对象 context 域对象 1.2.会话技术 C ...

  7. Spring mvc之SimpleUrlHandlerMapping

    1.配置文件如下 <bean id="method" class="com.xx.controller.xxxController" scope=&quo ...

  8. Spring的AOP AspectJ切入点语法详解(转)

    一.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示 ...

  9. Eclipse导入Maven项目出现:Could not calculate build plan: Plugin org.apache.maven.plugins:maven-war-plugin:2.2

    错误如下: Could not calculate build plan: Plugin org.apache.maven.plugins:maven-war-plugin:2.2 or one of ...

  10. CSS布局之BFC和IFC

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6708358.html <这是一篇css2-3的布局规 ...