题意:给定一些线段(s, e),起点为s,终点为e,求每一段线段被多少线段包含(不包括相等)

思路:很明显的树状数组题目。。但是做的时候想了挺久。。(下面的x为线段起点, y为线段终点)

做法1:先对线段进行排序,比较函数为 a.x < b.x || a.x == b.x && a.y > b.y;

接下来便依次插入树状数组中,插的时候左端点 +1, 右端点-1,这样求和时前面的线段自然消掉

统计是算sum(a[i].y)即可。。

但是这样我们发现落下了一种情况,就是把 x < a[i].x && y == a[i].y情况给消掉了,所以还要排序在统计一遍。。

这种做法我写完2300+ms过了。。

做法2:差不多的思路,但是结合把(x, y)当成二维坐标,这样我们发现其实上就是求其左上方的点有多少个。。采用poj2352stars做法即可。。需要判重。。

以为会快很多,。。没想到也要2200+ms才过。。

法1:

 /*
* author: yzcstc
* Created Time: 2013骞?9鏈?7鏃?鏄熸湡鍏?12鏃?7鍒?1绉?
* File Name: poj2481.cpp
*/
#include<iostream>
#include<sstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#define MXN 100010
#define MXM 1000000
#define M0(a) memset(a, 0, sizeof(a))
#define eps 1e-8
#define Inf 0x7fffffff
using namespace std;
struct oo{
int x, y, id;
bool operator <(const oo & b) const{
return x < b.x || x == b.x && y > b.y;
}
};
oo a[];
int cnt[], n, ans[]; int lowbit(int x){
return x & (-x) ;
} void updata(int x, int v){
while (x <= MXN){
cnt[x] += v;
x += lowbit(x);
}
} int get_sum(int x){
int ret = ;
while (x){
ret += cnt[x];
x -= lowbit(x);
}
return ret;
} bool cmp(const oo &a, const oo &b){
if (a.y < b.y) return true;
if (a.y == b.y && a.x < b.x) return true;
return false;
} void solve(){
M0(cnt);
M0(ans);
for (int i = ; i <= n; ++i){
scanf("%d%d", &a[i].x, &a[i].y);
++ a[i].x;
++ a[i].y;
a[i].id = i;
}
sort(a + , a + n + );
int sum = ;
for (int i = ; i <= n; ++i){
ans[a[i].id] = get_sum(a[i].y);
updata(a[i].x, );
updata(a[i].y, -);
}
sort(a + , a + n + , cmp);
int l = , r = ;
for (int i = ; i <= n; ++i){
while (l < i && a[l].y < a[i].y) ++l;
r = max(r, l);
while (r < i && a[r + ].x < a[i].x) ++r;
if (a[r].x == a[i].x) r = i;
if (r < i) ans[a[i].id] += (r - l + );
}
for (int i = ; i < n; ++i)
printf("%d ", ans[i]);
printf("%d\n", ans[n]);
} int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
while (scanf("%d", &n) != EOF && n){
solve();
}
fclose(stdin); fclose(stdout);
return ;
}

法2:

 /*
* author: yzcstc
* Created Time: 2013骞?9鏈?7鏃?鏄熸湡鍏?12鏃?7鍒?1绉?
* File Name: poj2481.cpp
*/
#include<iostream>
#include<sstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#define MXN 100010
#define MXM 1000000
#define M0(a) memset(a, 0, sizeof(a))
#define eps 1e-8
#define Inf 0x7fffffff
using namespace std;
struct oo{
int x, y, id;
bool operator <(const oo & b) const{
return x < b.x || x == b.x && y > b.y;
}
bool operator ==(const oo & b) const{
return x == b.x && y == b.y;
}
};
oo a[];
int cnt[], n, ans[]; int lowbit(int x){
return x & (-x) ;
} void updata(int x, int v){
while (x <= MXN){
cnt[x] += v;
x += lowbit(x);
}
} int get_sum(int x){
int ret = ;
while (x){
ret += cnt[x];
x -= lowbit(x);
}
return ret;
} void solve(){
M0(cnt);
M0(ans);
for (int i = ; i <= n; ++i){
scanf("%d%d", &a[i].x, &a[i].y);
++ a[i].x;
++ a[i].y;
a[i].id = i;
}
sort(a + , a + n + );
for (int i = ; i <= n; ++i){
ans[a[i].id] = get_sum(MXN) - get_sum(a[i].y - );
updata(a[i].y, );
}
int l = ;
for (int i = ; i <= n; ++i){
while (l < i){
if (a[l] == a[i]) break;
++l;
}
ans[a[i].id] -= (i - l);
}
for (int i = ; i < n; ++i)
printf("%d ", ans[i]);
printf("%d\n", ans[n]);
} int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
while (scanf("%d", &n) != EOF && n){
solve();
}
fclose(stdin); fclose(stdout);
return ;
}

poj2481的更多相关文章

  1. POJ-2481 Cows---树状数组的运用

    题目链接: https://vjudge.net/problem/POJ-2481 题目大意: if Si <= Sj and Ej <= Ei and Ei - Si > Ej - ...

  2. POJ-2481 Cows (线段树单点更新)

    题目大意:给n个区间,对于任意一个区间,求出能完全包含它并且长度比它长的区间的个数. 题目分析:将一个区间视为二位坐标系中的一个点,左端点视作横坐标,右端点视作纵坐标.则题目变成了求每个点的左上方.正 ...

  3. poj2481 Cows 树状数组

    题目链接:http://poj.org/problem?id=2481 解题思路: 这道题对每组数据进行查询,是树状数组的应用.对于二维的树状数组, 首先想到排序.现在对输入的数据按右值从大到小排序, ...

  4. poj2481树状数组解二维偏序

    按区间r降序排列,r相同按照l升序排列,两个区间相同时特判一下即可 /* 给定n个闭区间[l,r],如果对区间[li,ri],[lj,rj]来说, 有区间j严格包含(两个边界不能同时重合)在区间i内, ...

  5. POJ2481(树状数组:统计数字 出现个数)

    Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15405   Accepted: 5133 Description ...

  6. poj2481 Cows

    Description Farmer John's cows have discovered that the clover growing along the ridge of the hill ( ...

  7. POJ2481:Cows(树状数组)

    Description Farmer John's cows have discovered that the clover growing along the ridge of the hill ( ...

  8. 线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

    转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnl ...

随机推荐

  1. javascript 高级程序设计 十一

    接上一节的创建对象的模式: 原型模式: 对于prototype的理解:我们创建的函数都有一个prototype(原型)属性,这个属性是一个指针指向一个对象,而这个对象的用途是包含基于这个方法的 所有的 ...

  2. 2019年学Java开发有优势吗?

    随着信息科技的发展,在我们的日程生活和工作中到处充斥和使用着互联网信息技术.事实说明,互联网已经越来越广泛地深入到人们生活的方方面面,Java技术服务市场需求空缺会越来越大.学会一门IT技术,将拥有更 ...

  3. iOS8 UIAlertView键盘闪一下的问题

    if (SYSTEM_VERSION >= 8.0) { UIAlertController *alertCtrl = [UIAlertController alertControllerWit ...

  4. Servlet封装类

    Servlet 提供了四个封装类: public class ServletRequestWrapper extends java.lang.Object implements ServletRequ ...

  5. 记录点复习题目和linux学习

    哈希怎么底层.key放数组哪部分里面 HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体. 开网页怎么获取页面 linux 看进程的cpu 和内存占用率 看哪个端口被占用     ...

  6. linux 查看信息-服务器相关

    查看系统内核 查看磁盘信息 查看CPU的信息 查看内存相关信息

  7. tomcat运行监控脚本,自动启动

    参见:http://www.cnblogs.com/coffee_cn/p/8279165.html monitor.sh #!/bin/sh monitorlog=/usr/local/tomcat ...

  8. 关于部署传统的Dynamic Web项目

    现在大部分都是采用maven构建的项目,但是偶尔也会遇到一些较老的项目,采用的是传统的动态Web项目. 我最近碰到这样一个项目,项目用的jar包都放在了WEB-INF/lib目录下.之前的人采用的部署 ...

  9. 三连击(NOIP1998)

    题目链接:三连击 典型的打表题,但cgg今天不是教你怎么打表的,而是教你正解. 这题方法多样,比如递归求解也行,反正数据也不大. 在这里我提供另一种思路,我们枚举第一个数,即最小的一个数,然后分解它以 ...

  10. 2019.01.19 codeforces893F.Subtree Minimum Query(线段树合并)

    传送门 线段树合并菜题. 题意简述:给一棵带点权的有根树,多次询问某个点ppp子树内距离ppp不超过kkk的点的点权最小值,强制在线. 思路: 当然可以用dfsdfsdfs序+主席树水过去. 然而线段 ...