题意:有10万个点,10万个询问,没有更新,求L1<=L<=L2,R1<=R<=R2,有多少个,

其实转换一下:就是求一个矩形 (L1,R1) ----(L2,R2) 中有多少个点(很经典的题)

这里有比较神奇的做法:基于某种性质。

解析:

首先按照 L坐标排序,每个点 也弄成 (R,R,L,0,I)这种形式

矩形形式是: (L2,R2,L,-1,I) ;和

(L2,R2,R+1,1,I);

           那么,先按照L 排序;

struct Segment{
int x1,x2;
int y,t,id;
Segment(int x1 = 0,int x2 = 0,int y = 0,int t = 0,int id = 0):x1(x1),x2(x2),y(y),t(t),id(id){}
bool operator < (const Segment &a)const{
if(y != a.y) return y < a.y;
return abs(t) > abs(a.t);
}

这样;

 #include<bits/stdc++.h>
using namespace std;
const int N = ; #define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define Mid int mid = (l + r) >> 1
#define root 1,(N - 5),1 struct Segment{
int x1,x2;
int y,t,id;
Segment(int x1 = ,int x2 = ,int y = ,int t = ,int id = ):x1(x1),x2(x2),y(y),t(t),id(id){}
bool operator < (const Segment &a)const{
if(y != a.y) return y < a.y;
return abs(t) > abs(a.t);
}
}ss[N * ];
int sz;
struct SegmentTree{
int sum[N << ];
void pushup(int rt){
sum[rt] = sum[rt << ] + sum[rt << | ];
}
void build(int l,int r,int rt){
sum[rt] = ;
if(l == r) return;
Mid;
build(lson);
build(rson);
}
void update(int loc,int l,int r,int rt){
if(l == r){
sum[rt] ++;
return;
}
Mid;
if(loc <= mid) update(loc,lson);
else update(loc,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return sum[rt];
}
Mid;
int res = ;
if(L <= mid) res += query(L,R,lson);
if(mid + <= R) res += query(L,R,rson);
return res;
}
}sgt;
int res[N];
int main()
{
int n,m,l,r;
int l2,r2;
while(~scanf("%d",&n)){
sz = ;
for(int i = ; i < n ; i ++){
scanf("%d%d",&l,&r);
ss[sz ++] = Segment(r,r,l,);
}
scanf("%d",&m);
for(int i = ; i < m ; i ++){
scanf("%d%d%d%d",&l,&r,&l2,&r2);
ss[sz ++] = Segment(l2,r2,l,-,i);
ss[sz ++] = Segment(l2,r2,r + ,,i);
} for(int i = ; i < m ; i ++) res[i] = ;
sgt.build(root);
sort(ss,ss + sz);
for(int i = ; i < sz ; i ++){
if(ss[i].t == ) sgt.update(ss[i].x1,root);
else if(ss[i].t == -){
res[ ss[i].id ] -= sgt.query(ss[i].x1,ss[i].x2,root);
}
else{
res[ ss[i].id ] += sgt.query(ss[i].x1,ss[i].x2,root);
}
} for(int i = ; i < m ; i ++) printf("%d\n",res[i]);
}
return ;
}

先直接贴别人代码。

因为 我们是按照L 排序的,那么首先更新的事L在前的点。而它只可能对后面的点有影响,并且

是矩形 后面坐标 R1<=R<=R2;的点,因为询问时询问(R1,R2)区间,

只有一种是不符合的,R1<=R<=R2,但是L<L1的点 是不满足的 (想想)

于是我们 只有在去除这些更新的点就好了,所以对于会有:

else if(ss[i].t == -1){
res[ ss[i].id ] -= sgt.query(ss[i].x1,ss[i].x2,root);
}

在l1<=l<=l2的点都更新完了,我们在加上R+1所有的点,就是该矩形内有多少点的答案了,比较难想。

这道题也因为 区间比较大,所以普通 的二维树状数组 也是不行的

TOJ 4105的更多相关文章

  1. TOJ 4105 Lines Counting(离线树状数组)

    4105.   Lines Counting Time Limit: 2.0 Seconds   Memory Limit: 150000K Total Runs: 152   Accepted Ru ...

  2. TOJ 4105 Lines Counting (树状数组)

    题意:给定N条线段,每条线段的两个端点L和R都是整数.然后给出M个询问,每次询问给定两个区间[L1,R1]和[L2,R2],问有多少条线段满足:L1≤L≤R1 , L2≤R≤R2 ? 题解,采用离线做 ...

  3. TOJ 2776 CD Making

    TOJ 2776题目链接http://acm.tju.edu.cn/toj/showp2776.html 这题其实就是考虑的周全性...  贡献了好几次WA, 后来想了半天才知道哪里有遗漏.最大的问题 ...

  4. TOJ 1702.A Knight's Journey

    2015-06-05 问题简述: 有一个 p*q 的棋盘,一个骑士(就是中国象棋里的马)想要走完所有的格子,棋盘横向是 A...Z(其中A开始 p 个),纵向是 1...q. 原题链接:http:// ...

  5. TOJ 1139.Compromise

    2015-06-03 问题简述: 大概就是输入两段文本(用小写英文字母表示),分别用#表示一段话的结束输入,输出这两个文本的最长公共子序列. 简单的LCS问题,但是输入的是一段话了,而且公共部分比较是 ...

  6. bzoj:4105: [Thu Summer Camp 2015]平方运算

    Description   Input 第一行有三个整数N,M,p,分别代表序列的长度.平方操作与询问操作的总次数以及在平方操作中所要模的数.   接下来一行N个数代表一开始的序列{X1,X2,... ...

  7. 优先队列运用 TOJ 4123 Job Scheduling

    链接:http://acm.tju.edu.cn/toj/showp4123.html 4123.   Job Scheduling Time Limit: 1.0 Seconds   Memory ...

  8. 最小生成树 TOJ 4117 Happy tree friends

    链接http://acm.tju.edu.cn/toj/showp4117.html 4117.   Happy tree friends Time Limit: 1.0 Seconds   Memo ...

  9. TOJ 4120 Zombies VS Plants

    链接:http://acm.tju.edu.cn/toj/showp4120.html 4120.   Zombies VS Plants Time Limit: 1.0 Seconds   Memo ...

随机推荐

  1. k8s master init and add node

    目录 一. add google apt-key 二. k8s master init 三. k8s node add to master cluster(use this command when ...

  2. Springboot邮箱接口(使用个人邮箱发送邮件)

    近期项目使用邮件验证,这里使用个人邮箱进行测试,记录开发笔记 SpringBoot自带短信接口 maven pom.xml 引入: <dependency> <groupId> ...

  3. 冒泡法排序参考(Java)

    package com.swift; public class Maopao { //冒泡法 public static void main(String[] args) { int[] arr= { ...

  4. iOS开发--使用OpenSSL生成私钥和公钥的方法

    最近要在新项目中使用支付宝钱包进行支付,所以要调研对接支付宝的接口,支付宝开放平台采用了RSA安全签名机制,开发者可以通过支付宝   公钥验证消息来源,同时可使用自己的私钥对信息进行加密,所以需要在本 ...

  5. Ubuntu创建应用快捷方式

    Ubuntu创建应用快捷方式 新建一个.desktop文件 vi eclipse.desktop 然后又进行编辑 [Desktop Entry] Encoding=UTF-8 Name=eclipse ...

  6. Bzoj 1083: [SCOI2005]繁忙的都市 (最小生成树)

    Bzoj 1083: [SCOI2005]繁忙的都市 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1083 此题是最小瓶颈生成树的裸题. ...

  7. 【dp】拔河比赛

    01背包:感谢ZCK大佬 题目描述 学校举行拔河比赛,所有的人被分成了两组,每个人必须(且只能够)在其中的一组,要求两个组的人数相差不能超过1,且两个组内的所有人体重加起来尽可能地接近. 输入 输入中 ...

  8. java代码生成二维码

    java代码生成二维码一般步骤 常用的是Google的Zxing来生成二维码,生成的一般步骤如下: 一.下载zxing-core的jar包: 二.需要创建一个MatrixToImageWriter类, ...

  9. C++代码学习之一:组合模式例子

    #include"AbstractFile.h" void AbstractFile::add(AbstractFile*) { } void AbstractFile::remo ...

  10. perl学习之HERE文档

    Perl的here文档机制是从UNIX shell中的here文档机制派生而来的. 和在shell中一样,Perl中的here文档也是面向行的引用表单,要求提供<<运算符,其后跟随一个初始 ...