【十分不错】【离线+树状数组】【TOJ4105】【Lines Counting】

原创 2015年07月11日 02:04:53

On the number axis, there are N lines. The two endpoints L and R of each line are integer. Give you M queries, each query contains two intervals: [L1,R1] and [L2,R2], can you count how many lines satisfy this property: L1≤L≤R1 and L2≤R≤R2?


Input

First line will be a positive integer N (1≤N≤100000) indicating the number of lines. Following the coordinates of the N lines' endpoints L and R will be given (1≤L≤R≤100000). Next will be a positive integer M (1≤M≤100000) indicating the number of queries. Following the four numbers L1,R1,L2 and R2 of the M queries will be given (1≤L1≤R1≤L2≤R2≤100000).

Output

For each query output the corresponding answer.


双区间查询
第一个区间就裸的[1...l1-1] [l2..r2] 
   [1.......r1] [l2..r2]
      用vector (Q[i])维护~(i为l1-1,r1的值)
       表示 [1...i][Q[i][j].l2...Q[i][j].r2] 表示上述~

第二个区间 当枚举i的时候,内循环枚举线段到s[p].x<=i,s[p].y加入a[]来维护终止点
  因为起止点排好序了
  一定满足Q[i]的[1....i]
  a[]树状数组来维护好l2,r2.

原理理解后 代码很简单。。
直接贴朱神的代码了
复杂度 比较难表述 但是显然是接受范围

(当初考虑l,r不好存。。开数组不好存,才知道可以表示在数组内就好)
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;

const int N=100000;

int a[100005];

int inline lowbit(int x){
	return x&(-x);
}
void add(int p,int val){
	while(p<=N){
		a[p]=(a[p]+val);
		p+=lowbit(p);
	}
}
int sum(int p){
	int ans=0;
	while(p>0){
		ans=(ans+a[p]);
		p-=lowbit(p);
	}
	return ans;
}

struct Query{
	int l,r;
	int oriid;
	int orip;
	Query(){}
	Query(int a,int b,int c,int d):l(a),r(b),oriid(c),orip(d){}
};

vector<Query> qs[100005];

int ans[100005][2];

struct Pair{
	int x,y;
	Pair(){}
	Pair(int a,int b):x(a),y(b){}
	bool operator<(const Pair&b)const{
		return x<b.x;
	}
}side[100005];

int main()
{
	int n,m;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d%d",&side[i].x,&side[i].y);
		}
		sort(side,side+n);
		for(int i=0;i<=N;i++) qs[i].clear();
		scanf("%d",&m);
		int maxq=0;
		for(int i=0;i<m;i++){
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			qs[a-1].push_back(Query(c,d,i,0));
			qs[b].push_back(Query(c,d,i,1));
			maxq=max(maxq,(max(a,b)));
		}

		memset(a,0,sizeof(a));
		int sp=0;
		for(int i=0;i<=maxq;i++){
			while(sp<n&&side[sp].x==i){
				add(side[sp].y,1);
				sp++;
			}
			for(int j=0;j<qs[i].size();j++){
				int ans1=sum(qs[i][j].l-1);
				int ans2=sum(qs[i][j].r);
				ans[qs[i][j].oriid][qs[i][j].orip]=ans2-ans1;
			}
		}
		for(int i=0;i<m;i++){
			printf("%d\n",ans[i][1]-ans[i][0]);
		}
	}
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

[CSAPP笔记][第八章异常控制流][呕心沥血千行笔记]

此地址观看更佳异常控制流 控制转移 控制流 系统必须能对系统状态的变化做出反应,这些系统状态不是被内部程序变量捕获,也不一定和程序的执行相关。现代系统通过使控制流 发生突变对这些情况做出反应。我们称这...

HDU 4358 Boring counting(树的遍历+树状数组+离散化+离线处理)

HDU 4358 Boring counting(树的遍历+树状数组+离散化+离线处理) 分析:        首先读入所有的节点权重存在nodes[n]中,然后读入n-1条边,1为根节点.把整个图做...

sdut2610---Boring Counting(离线+树状数组+离散化)

Boring Counting Time Limit: 3000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 In this problem yo...

HDU 4358 Boring counting(树状数组离线操作+欧拉序列)

题目大意:

HDU 5862 Counting Intersections(树状数组+扫描线+离散化)

Counting Intersections Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java...

HDU-5862-Counting Intersections(树状数组+离散化+扫描线)

链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 题意:给出与坐标轴平行的线段,求所有线段的交点个数 题解:先将数据离散化,将两类线段...

HDU 4638 Group 树状数组离线

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4638 题意:给定一个长度为n的数组,数组中元素为1到n,询问某个区间内有多少段连续的数字 思路:之前用...

hdu 4417 离线树状数组

题意: 给你一个数列,然后有m次查询,每次查询一段区间 [l,r] 内不大于 h 的值的个数。 解法: 离线 树状数组 1、若 a[i].h  > q[j].h,则从 i 以后的 a[i].h...

[离线+树状数组 || 主席树]BZOJ1878: [SDOI2009]HH的项链

题意给出一个n个数的数列。m次询问,每次求[L,R]区间中包含了多少种不同的数字。 (N ≤ 50000,M ≤ 200000)题解水题,解法很多。 我这里主要讲两种解法,实际上主要思想都差不多。...
  • CHHNZ
  • CHHNZ
  • 2017年04月25日 07:51
  • 248

HDU 4777 Rabbit Kingdom(树状数组+离线预处理)

Problem Description   Long long ago, there was an ancient rabbit kingdom in the forest. Every rabbi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【十分不错】【离线+树状数组】【TOJ4105】【Lines Counting】
举报原因:
原因补充:

(最多只允许输入30个字)