题意:给定一些线段(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. hdu 1558 (线段相交+并查集) Segment set

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1558 题意是在坐标系中,当输入P(注意是大写,我当开始就wa成了小写)的时候输入一条线段的起点坐标和终点坐 ...

  2. 常用的TCP Option

    当前,TCP常用的Option如下所示———— Kind (Type) Length Name Reference 描述 & 用途 0 1 EOL RFC 793 选项列表结束 1 1 NOP ...

  3. svn 回滚文件修改

    取消对代码的修改分为两种情况:   第一种情况:改动没有被提交(commit). 这种情况下,使用svn revert就能取消之前的修改. svn revert用法如下: # svn revert [ ...

  4. Luogu 1273 有线电视网 - 树形背包

    Description 树形背包, 遍历到一个节点, 枚举它的每个子节点要选择多少个用户进行转移. Code #include<cstring> #include<cstdio> ...

  5. postfix发信提示 Error: too many connectino from

    查看提示,很明显是提示连接数过多导致的. 有提示上面的信息,看提示的IP地址是一个网关的地址,使用netstat -ano|grep ':25'|wc -l 看了下,25端口的连接的IP地址,几乎全是 ...

  6. macOS X Mount NFS Share / Set an NFS Client

    last updated November 3, 2018 in CategoriesLinux, Mac OS X, UNIX How do I access my enterprise NAS s ...

  7. strace使用

    统计信息 -c -- count time, calls, and errors for each syscall and report summary 输出结果到文件 -o   例如 strace ...

  8. Git使用基础篇(zz)

    Git使用基础篇 您的评价:          收藏该经验       Git是一个分布式的版本控制工具,本篇文章从介绍Git开始,重点在于介绍Git的基本命令和使用技巧,让你尝试使用Git的同时,体 ...

  9. ''TclError: no display name and no $DISPLAY environment variable''解决方法

    在模块前写入一下代码: import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt 具体解释见   http://m ...

  10. python入门之文件处理

    1.读取文件 f=open(file="C:\BiZhi\新建文本文档.txt",mode="r",encoding="utf-8") da ...