poj2481
题意:给定一些线段(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的更多相关文章
- POJ-2481 Cows---树状数组的运用
题目链接: https://vjudge.net/problem/POJ-2481 题目大意: if Si <= Sj and Ej <= Ei and Ei - Si > Ej - ...
- POJ-2481 Cows (线段树单点更新)
题目大意:给n个区间,对于任意一个区间,求出能完全包含它并且长度比它长的区间的个数. 题目分析:将一个区间视为二位坐标系中的一个点,左端点视作横坐标,右端点视作纵坐标.则题目变成了求每个点的左上方.正 ...
- poj2481 Cows 树状数组
题目链接:http://poj.org/problem?id=2481 解题思路: 这道题对每组数据进行查询,是树状数组的应用.对于二维的树状数组, 首先想到排序.现在对输入的数据按右值从大到小排序, ...
- poj2481树状数组解二维偏序
按区间r降序排列,r相同按照l升序排列,两个区间相同时特判一下即可 /* 给定n个闭区间[l,r],如果对区间[li,ri],[lj,rj]来说, 有区间j严格包含(两个边界不能同时重合)在区间i内, ...
- POJ2481(树状数组:统计数字 出现个数)
Cows Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 15405 Accepted: 5133 Description ...
- poj2481 Cows
Description Farmer John's cows have discovered that the clover growing along the ridge of the hill ( ...
- POJ2481:Cows(树状数组)
Description Farmer John's cows have discovered that the clover growing along the ridge of the hill ( ...
- 线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)
转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnl ...
随机推荐
- Java.Class
Class类 1. Class继承自Object. 2. .class 和 instance.getClass()的区别 Ref[1] Reference 1. .class http://stack ...
- Next generation sequencing (NGS)二代测序数据预处理与分析
二代测序原理: 1.DNA待测文库构建. 超声波把DNA打断成小片段,一般200--500bp,两端加上不同的接头2.Flowcell.一个flowcell,8个channel,很多接头3.桥式PCR ...
- 全局组建封装(挂载到vue实例的原型中,通过this访问)
主题:组建的封装 一:install注册的全局封装(v-grid九宫格组建) 1.九宫格的封装主要有三个api 点击功能 每行个数 是否隐藏边框 ...
- c++文件的输入输出
emmm,错误地方还请指出(以下代码复制粘贴会报错,我用codeblocks测试过,不知道为什么qaq) 头文件#include < fstream > 这里ofstream是" ...
- Luogu2022 有趣的数-二分答案+数位DP
Solution 我好像写了一个非常有趣的解法233, 我们可以用数位$DP$ 算出比$N$小的数中 字典序比 $X$ 小的数有多少个, 再和 $rank$进行比较. 由于具有单调性, 显然可以二分答 ...
- BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点
Solution 输入中没有出现过的矿场点是不用考虑的, 所以不用考虑只有 一个点 的点双联通分量. 要使某个挖矿点倒塌, 相当于割去这个点, 所以我们求一遍割点和点双联通分量. 之后的点双联通分量构 ...
- 20172325 2017-2018-2 《Java程序设计》第十一周学习总结
20172325 2017-2018-2 <Java程序设计>第十一周学习总结 教材学习内容总结 Android简介 Android操作系统是一种多用户的Linux系统,每个应用程序作为单 ...
- django添加装饰器
引入模块: from django.utils.decorators import method_decorator 添加:@method_decorator(func) from django.ut ...
- Longest Turbulent Subarray LT978
A subarray A[i], A[i+1], ..., A[j] of A is said to be turbulent if and only if: For i <= k < j ...
- IOS初级:UIwindow
AppDelegate.h @property (strong, nonatomic) UIWindow *window; AppDelegate.m - (BOOL)application:(UIA ...