先看看上一个题:

题目大意是: 矩阵中有N个被标记的元素,然后针对每一个被标记的元素e(x,y),你要在所有被标记的元素中找到一个元素E(X,Y),使得X>x并且Y>y,如果存在多个满足条件的元素,先比较X,选择X最小的那个,如果还是有很多满足条件的元素,再比较Y,选择Y最小的元素,如果不存在就输出两个-1;

分析: 直接暴力就行了

这个题目大意:

这个题是上个题的坚强版,每次会增加或减少一个点,仍然找到一个元素E(X,Y),使得X>x并且Y>y;

最多有200000次操作,每次只能是O(logn)的查询,行有1000000000之大,但是最多只会出现200000个不同的行,所以要离散化一下。然后对于每行的所有列用set去存,用线段树来维护每一行的出现的最大列,具体看代码吧

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<set>
#include<queue>
#include<stack>
#define MAXN 200010 using namespace std; int Max[MAXN<<], b[MAXN], c[MAXN], cnt;
set<int>sy[MAXN];
struct node
{
int x, y, flag;
} n[];
void PushUp(int root)
{
Max[root]=max(Max[root*],Max[root*+]);
}
void Update(int p, int x, int L, int R, int root) //a[p]=x,并且更新最大值
{
if(L==R)
{
Max[root]=x;
return ;
}
int mid=(L+R)/;
if(p<=mid) Update(p,x,L,mid,root*);
else Update(p,x,mid+,R,root*+);
PushUp(root);
}
int Query(int num, int post_ll, int L, int R, int root)//从post_ll这个位置开始向右查找,返回大于等于num的位置下表
{
if(L==R)
{
if(Max[root]>=num) return L;
else return -;
}
int ans=-, mid=(L+R)/;
if(post_ll<=mid&&Max[root*]>=num) ans=Query(num,post_ll,L,mid,root*);
if(ans!=-) return ans;
if(Max[root*+]>=num) ans=Query(num,post_ll,mid+,R,root*+);
return ans;
} int BS1(int x)
{
int low=, high=cnt, mid;
while(low<=high)
{
mid=low+high>>;
if(c[mid]==x) return mid;
else if(c[mid]>x) high=mid-;
else low=mid+;
}
}
int BS2(int x)
{
int low=, high=cnt, mid, ans=-;
while(low<=high)
{
mid=low+high>>;
if(c[mid]>x)
{
ans=mid;
high=mid-;
}
else low=mid+;
}
return ans;
}
void init(int nn)
{
for(int i=; i<nn; i++)
sy[i].clear();
memset(Max,-,sizeof(Max));
}
int main()
{
int nn, x, tot, ans, cas=;
char cmd[];
while(scanf("%d",&nn)!=EOF&&nn)
{
cnt=tot=;
init(nn);
for(int i=; i<nn; i++)
{
scanf("%s%d%d",cmd,&n[i].x,&n[i].y);
if(!strcmp(cmd,"add"))
{
n[i].flag=;
b[tot++]=n[i].x;
}
else if(!strcmp(cmd,"find"))
n[i].flag=;
else n[i].flag=;
}
sort(b,b+tot);
c[]=b[];
for(int i=; i<tot; i++)
{
if(b[i]!=b[i-])
c[++cnt]=b[i];
}//离散化
printf("Case %d:\n",++cas);
for(int i=; i<nn; i++)
{
if(n[i].flag==)
{
x=BS1(n[i].x);
sy[x].insert(n[i].y);
Update(x,*(--sy[x].end()),,cnt,);
}
else if(n[i].flag==)
{
x=BS2(n[i].x);
if(x==-)
{
puts("-1");
continue ;
}
ans=Query(n[i].y+,x,,cnt,);
if(ans==-) printf("-1\n");
else printf("%d %d\n",c[ans],*(sy[ans].lower_bound(n[i].y+)));
}
else
{
x=BS1(n[i].x);
sy[x].erase(n[i].y);
if(!sy[x].size())
{
Update(x,-,,cnt,);
}
else Update(x,*(--sy[x].end()),,cnt,);
}
}
printf("\n");
}
return ;
}

sdut 2159 Ivan comes again!(2010年山东省第一届ACM大学生程序设计竞赛) 线段树+离散的更多相关文章

  1. sdut 2153 Clockwise (2010年山东省第一届ACM大学生程序设计竞赛)

    题目大意: n个点,第i个点和第i+1个点可以构成向量,问最少删除多少个点可以让构成的向量顺时针旋转或者逆时针旋转. 分析: dp很好想,dp[j][i]表示以向量ji(第j个点到第i个点构成的向量) ...

  2. Hello World! 2010年山东省第一届ACM大学生程序设计竞赛

    Hello World! Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that Ivan gives Saya three problem ...

  3. 2010年山东省第一届ACM大学生程序设计竞赛 Balloons (BFS)

    题意 : 找联通块的个数,Saya定义两个相连是 |xa-xb| + |ya-yb| ≤ 1 ,但是Kudo定义的相连是 |xa-xb|≤1 并且 |ya-yb|≤1.输出按照两种方式数的联通块的各数 ...

  4. Phone Number 2010年山东省第一届ACM大学生程序设计竞赛

    Phone Number Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that if a phone number A is anothe ...

  5. [2011山东省第二届ACM大学生程序设计竞赛]——Identifiers

    Identifiers Time Limit: 1000MS Memory limit: 65536K 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?act ...

  6. sdut Mountain Subsequences 2013年山东省第四届ACM大学生程序设计竞赛

    Mountain Subsequences 题目描述 Coco is a beautiful ACMer girl living in a very beautiful mountain. There ...

  7. [2012山东省第三届ACM大学生程序设计竞赛]——n a^o7 !

    n a^o7 ! 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2413 Time Lim ...

  8. angry_birds_again_and_again(2014年山东省第五届ACM大学生程序设计竞赛A题)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2877 题目描述 The problems ca ...

  9. [2012山东省第三届ACM大学生程序设计竞赛]——Mine Number

    Mine Number 题目:http://acm.sdut.edu.cn/sdutoj/problem.php? action=showproblem&problemid=2410 Time ...

随机推荐

  1. 使用SoundPool播放音效

    针对应用程序经常需要播放密集.短促的音效,因为MediaPlayer存在如下缺点: 1.资源占用量较高.延迟时间较长. 2.不支持多个音效同时播放. SoundPool使用音效池的概念来管理多个短促的 ...

  2. 选择最适合你的Linux学习方法

    我们知道Linux只是一个内核,现在的Linux操作系统底层都是用这个内核,包括Android手机,所以Linux操作系统其实是将Linux内核与应用软件做一个打包,我们称之为Linux发行版.现在比 ...

  3. 统计sql语句执行效率

    --统计sql语句执行效率SELECT (total_elapsed_time / execution_count)/1000 N'平均时间ms' ,total_elapsed_time/1000 N ...

  4. 投资统计查询sql

    select COUNT(*) from YYD_Users_RegInfo where regTime between '2016-07-11 00:00:00' and '2016-07-11 2 ...

  5. Windows多线程编程总结

    1 内核对象 1 .1 内核对象的概念 内核对象是内核分配的一个内存块,这种内存块是一个数据结构,表示内核对象的各种特征.并且只能由内核来访问.应用程序若需要访问内核对象,需要通过操作系统提供的函数来 ...

  6. python框架(flask/django/tornado)比较

    一.对外数据接口 三者作为web框架,都是通过url映射对外的接口 flask:以decorator的形式,映射到函数中 django:以字典形式,映射到函数 tornado: 以字典形式,映射到类中 ...

  7. 本节向大家介绍一下UML建模误区

    本节向大家介绍一下UML建模误区,这里向大家介绍九个误区,希望通过本节的学习,你对UML建模有清晰的认识,以免在以后使用过程中产生不必要的麻烦.下面让我们一起来看一下这些建模误区吧. UML建模误区 ...

  8. [windows操作系统]内核性能剖析

    profile这个词有(1)外形.轮廓.外观.形象(2)印象.形象(3)人物简介(4)剖面图.侧面图等意.在计算机和通讯协议中这个词也非常常见.这里主要介绍一下它在软件系统性能分析领域的一个释义. 翻 ...

  9. JAVA工作方式

    public class Hellow { int eyes = 2; int ears = 2; int legs = 4; void run(){ //方法 System.out.println( ...

  10. IOS UTF8中文字母数字 组合时长度截取

    //计算总共字数和限制字数的Index位置 -(NSMutableArray *) unicodeLengthOfString: (NSString *) text { NSMutableArray ...