题意:给定一些线段(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. 找不到或无法加载主类(Could not find or load main class )

    在Linux环境下,写了一个简单的java程序,通过javac编译成class文件,然后用java 运行的时候,报了这个错误, 搜了一下,可能是classpath的问题,所以用echo $CLASSP ...

  2. 利用七牛存储7天远程自动备份LINUX服务器

    受服务器空间制约,我们不可能在VPS上每天都备份一份新的网站数据,一是没必要,二是占空间.我们折中一下,采用星期命名,每次备份将覆盖上星期同一天的文件.从而只备份7份数据,不至于占用特别大的空间. 如 ...

  3. linux shell 重定向中的 & 符号

    写一个简单的 demo 示例 #include <stdio.h> int main() { fprintf(stdout, "stdout output\n"); f ...

  4. Python3字符编码

    编码 字符串是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节 ...

  5. Netty 源码 Channel(二)主要类

    Netty 源码 Channel(二)主要类 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Channel 类图 二. ...

  6. mybatis 一次执行多条语句

    现在的一些互联网应用 为了提高性能,现在一般比较少的使用外键.不是不用,只是在创建数据库不标明外键关系,用程序去维护. 为了维护数据一致性,我们需要手动完成相关数据的删除 比如用户和用户的关注 当用户 ...

  7. Java中TreeMap的基本操作

    TreeSet有四种种构造函数可以初始化 在代码中主要列出了常用的三种: 构造方法摘要 TreeSet()           构造一个新的空 set,该 set 根据其元素的自然顺序进行排序. Tr ...

  8. NOIP模拟测试1(2017081501)

    好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...

  9. hibernate 的evict 和clear

    摘自百度知道:http://zhidao.baidu.com/question/63663640.html 问: 先创建一个Student,然后调用session.save方法,然后再调用evict方 ...

  10. mysqldb mysql_config

    在安装mysqldb Python的时候会用到mysql_config,但是正常安装的MySQL环境下是没有这个文件的,这个文件在Linux下是可执行文件,所以需要到mysql官方网站上下载MySQL ...