Stars

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6676    Accepted Submission(s): 2659

Problem Description
Astronomers
often examine star maps where stars are represented by points on a
plane and each star has Cartesian coordinates. Let the level of a star
be an amount of the stars that are not higher and not to the right of
the given star. Astronomers want to know the distribution of the levels
of the stars.

For
example, look at the map shown on the figure above. Level of the star
number 5 is equal to 3 (it's formed by three stars with a numbers 1, 2
and 4). And the levels of the stars numbered by 2 and 4 are 1. At this
map there are only one star of the level 0, two stars of the level 1,
one star of the level 2, and one star of the level 3.

You are to write a program that will count the amounts of the stars of each level on a given map.

 
Input
The
first line of the input file contains a number of stars N
(1<=N<=15000). The following N lines describe coordinates of stars
(two integers X and Y per line separated by a space,
0<=X,Y<=32000). There can be only one star at one point of the
plane. Stars are listed in ascending order of Y coordinate. Stars with
equal Y coordinates are listed in ascending order of X coordinate.
 
Output
The
output should contain N lines, one number per line. The first line
contains amount of stars of the level 0, the second does amount of stars
of the level 1 and so on, the last line contains amount of stars of the
level N-1.
 
Sample Input
5
1 1
5 1
7 1
3 3
5 5
 
Sample Output
1
2
1
1
0
 题解:给出n个点的坐标,定义一个点的等级为这个点的左下方的点的个数,输出等级为0的点的个数,等级为1的点的个数,一直输出到等级为n-1的点的个数
 
做这个题真是曲折啊,没读清题意就开始写,首先Stars are listed in ascending order of Y coordinate,Stars with equal Y coordinates are listed in ascending order of X coordinate没看到,人家题上给的数据本来就是以y轴升序排列的,自己还傻逼的排序,另外The output should contain N lines这句没看见,自己是以空格输出。。。然后就是思路了,自己竟然想着把点都存在一个数组里面,再用二分去找点的个数。。。。好麻烦的思路,直接ans【sum】++不就妥了么。。。。最后还是超时,怎么办呐,极限数据不对,哪个数据?0呗,如果是0点,update就死循环了。。。
可能麻烦点,但自己的代码还是对的,以后写代码还是要看清题,找到最简单的思路,写的也好写点;
简单代码:
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
//#define LOCAL
const int MAXM=;
const int MAXN=;
/*struct Node{
int x,y;
};*/
int tree[MAXM+],ans[MAXN];//,die[MAXN];
//Node dt[MAXN];
/*int cmp(Node a,Node b){
if(a.y!=b.y){
return a.y<b.y;
}
else return a.x<b.x;
}*/
int lowbit(int x){
return x&(-x);
}
void update(int x){
while(x<=MAXM){
tree[x]++;
x+=lowbit(x);
}
}
int SUM(int x){
int temp=;
while(x>){
temp+=tree[x];
x-=lowbit(x);
}
return temp;
}
/*int erfen(int l,int r,int x){
int mid;
while(l<=r){
mid=(l+r)>>1;
if(die[mid]>x)r=mid-1;
else l=mid+1;
}
return l;
}*/
int main(){
/* #ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif*/
int N;
int a;
while(~scanf("%d",&N)){
memset(tree,,sizeof(tree));
memset(ans,,sizeof(ans));
for(int i=;i<N;i++){
scanf("%d%*d",&a);
a++;
ans[SUM(a)]++;update(a);
// scanf("%d%d",&dt[i].x,&dt[i].y);
}
//sort(dt,dt+N,cmp);
/* for(int i=0;i<N;i++){
die[i]=SUM(dt[i].x);
update(dt[i].x);
}
sort(die,die+N);
for(int i=0;i<N;i++){
int temp=0,t=erfen(0,N-1,i);
// printf("%d**%d**%d\n",die[t-1],i,t);
temp=t;
ans[i]=temp;
// printf("%d\n",ans[i]);
}*/
for(int i=;i<N;i++){
/* if(i){
printf(" ");
}*/
// printf("%d",i==0?ans[i]:ans[i]-ans[i-1]);
printf("%d\n",ans[i]);
} }
return ;
}

刚开始写的也ac了:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
//#define LOCAL
const int MAXM=;
const int MAXN=;
struct Node{
int x,y;
};
int tree[MAXM+],die[MAXN],ans[MAXN];
Node dt[MAXN];
/*int cmp(Node a,Node b){
if(a.y!=b.y){
return a.y<b.y;
}
else return a.x<b.x;
}*/
int lowbit(int x){
return x&(-x);
}
void update(int x){
while(x<=MAXM){
tree[x]++;
x+=lowbit(x);
}
}
int SUM(int x){
int temp=;
while(x){
temp+=tree[x];
x-=lowbit(x);
}
return temp;
}
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
int N;
while(~scanf("%d",&N)){
for(int i=;i<N;i++){
scanf("%d%d",&dt[i].x,&dt[i].y);
dt[i].x++;
}
//sort(dt,dt+N,cmp);
memset(tree,,sizeof(tree));
for(int i=;i<N;i++){
die[i]=SUM(dt[i].x);
update(dt[i].x);
}
sort(die,die+N);
for(int i=,j=;i<N;i++){
int temp=;
while(die[j]==i){
j++;temp++;
}
ans[i]=temp;
}
for(int i=;i<N;i++){
//if(i)printf(" ");
printf("%d\n",ans[i]);
}
// puts("");
}
return ;
}

刚开始发现超时改成二分找了,更快点的最后也ac了:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
//#define LOCAL
const int MAXM=;
const int MAXN=;
struct Node{
int x,y;
};
int tree[MAXM+],die[MAXN],ans[MAXN];
Node dt[MAXN];
/*int cmp(Node a,Node b){
if(a.y!=b.y){
return a.y<b.y;
}
else return a.x<b.x;
}*/
int lowbit(int x){
return x&(-x);
}
void update(int x){
while(x<=MAXM){
tree[x]++;
x+=lowbit(x);
}
}
int SUM(int x){
int temp=;
while(x){
temp+=tree[x];
x-=lowbit(x);
}
return temp;
}
int erfen(int l,int r,int x){
int mid;
while(l<=r){
mid=(l+r)>>;
if(die[mid]>x)r=mid-;
else l=mid+;
}
return l;
}
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
int N;
while(~scanf("%d",&N)){
for(int i=;i<N;i++){
scanf("%d%d",&dt[i].x,&dt[i].y);
dt[i].x++;
}
//sort(dt,dt+N,cmp);
memset(tree,,sizeof(tree));
for(int i=;i<N;i++){
die[i]=SUM(dt[i].x);
update(dt[i].x);
}
sort(die,die+N);
for(int i=;i<N;i++){
int temp=,t=erfen(,N-,i);
// printf("%d**%d**%d\n",die[t-1],i,t);
temp=t;
ans[i]=temp;
// printf("%d\n",ans[i]);
}
for(int i=;i<N;i++){
//if(i)printf(" ");
printf("%d\n",i==?ans[i]:ans[i]-ans[i-]);
}
// puts("");
}
return ;
}

线段树来一发:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=;
#define L tree[root].l
#define R tree[root].r
#define S tree[root].sum
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r struct Node{
int l,r,sum;
};
Node tree[MAXN<<];
int res[MAXN>>];
int ans;
void build(int root,int l,int r){
L=l;R=r;
S=;
if(l==r)return;
int mid=(l+r)>>;
build(lson);
build(rson);
}
void update(int root,int x){
if(L==x&&R==x){
S++;
return;
}
int mid=(L+R)>>;
if(mid>=x)update(root<<,x);
else update(root<<|,x);
S=tree[root<<].sum+tree[root<<|].sum;
}
void query(int root,int x){
if(L>=&&R<=x){
ans+=S;
return;
}
int mid=(L+R)>>;
if(mid>=)query(root<<,x);
if(mid<x)query(root<<|,x);
}
int main(){
int N,a;
while(~scanf("%d",&N)){
build(,,MAXN-);
memset(res,,sizeof(res));
for(int i=;i<N;i++){
scanf("%d%*d",&a);
a++;
ans=;
query(,a);
res[ans]++;
update(,a);
}
for(int i=;i<N;i++)printf("%d\n",res[i]);
}
return ;
}

Stars(树状数组+线段树)的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  2. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  3. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  4. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  6. 数据结构--树状数组&&线段树--基本操作

    随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...

  7. BZOJ_1901_&_ZJU_2112_Dynamic_Rankings_(主席树+树状数组/线段树+(Treap/Splay))

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l, ...

  8. BZOJ 3333 排队计划 树状数组+线段树

    题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...

  9. 第十四个目标(dp + 树状数组 + 线段树)

    Problem 2236 第十四个目标 Accept: 17    Submit: 35 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  10. Curious Robin Hood(树状数组+线段树)

    1112 - Curious Robin Hood    PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 ...

随机推荐

  1. Android 图片平铺效果实现的3种方法

    Html中平铺的效果,那么我们都是怎么样才能实现的那,我们其实主要用到的就是api,我们一开始new一个bitmap,就可以了,那么我们就来说说第二种方法,那就在用到了xml,上面我们说了两个方法,但 ...

  2. linux 程序运行监控

    一 . 使用supervise 是daemon-tools 的一个功能,系统的守护进程.在进程挂掉的时候可以自动重启. 二   安装 wget http://cr.yp.to/daemontools/ ...

  3. [原创]浅谈如何使用gcc开发NT核心驱动程序

    原文链接:[原创]浅谈如何使用gcc开发NT核心驱动程序 一谈到在 Win NT 下开发核心驱动程序,可能不少人首先都会想到微软“正统”的VC来.诚然,用VC 配合 WINDDK 的确工作的不错,但或 ...

  4. 分析java中clone()方法 (转载+修改)

    Java中的clone() 方法 java所有的类都是从java.lang.Object类继承而来的,而Object类提供下面的方法对对象进行复制. protected native Object c ...

  5. JAVA 中的RMI是什么

    RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台 ...

  6. 剑指offer26 复杂链表的复制

    /* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : ...

  7. 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类

    1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...

  8. 一个简单的游标删除SQL SERVER表

    use databaseName declare @tblname char(100) declare @sql char(5000) declare table_cursor cursor for ...

  9. xcode KVC:Key Value Coding 键值编码

    赋值 // 能修改私有成员变量 - (void)setValue:(id)value forKey:(NSString *)key; - (void)setValue:(id)value forKey ...

  10. IE6存在的一些兼容

    1.文档类型的声明. 产生条件:IE6浏览器,当我们没有书写这个文档声明的时候,会触发IE6浏览器的怪异解析现象: 解决办法:书写文档声明. 2.不同浏览器当中,很多的标签的默认样式不同,如默认的外部 ...