sdut 2159 Ivan comes again!(2010年山东省第一届ACM大学生程序设计竞赛) 线段树+离散
先看看上一个题:
题目大意是: 矩阵中有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大学生程序设计竞赛) 线段树+离散的更多相关文章
- sdut 2153 Clockwise (2010年山东省第一届ACM大学生程序设计竞赛)
题目大意: n个点,第i个点和第i+1个点可以构成向量,问最少删除多少个点可以让构成的向量顺时针旋转或者逆时针旋转. 分析: dp很好想,dp[j][i]表示以向量ji(第j个点到第i个点构成的向量) ...
- Hello World! 2010年山东省第一届ACM大学生程序设计竞赛
Hello World! Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that Ivan gives Saya three problem ...
- 2010年山东省第一届ACM大学生程序设计竞赛 Balloons (BFS)
题意 : 找联通块的个数,Saya定义两个相连是 |xa-xb| + |ya-yb| ≤ 1 ,但是Kudo定义的相连是 |xa-xb|≤1 并且 |ya-yb|≤1.输出按照两种方式数的联通块的各数 ...
- Phone Number 2010年山东省第一届ACM大学生程序设计竞赛
Phone Number Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that if a phone number A is anothe ...
- [2011山东省第二届ACM大学生程序设计竞赛]——Identifiers
Identifiers Time Limit: 1000MS Memory limit: 65536K 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?act ...
- sdut Mountain Subsequences 2013年山东省第四届ACM大学生程序设计竞赛
Mountain Subsequences 题目描述 Coco is a beautiful ACMer girl living in a very beautiful mountain. There ...
- [2012山东省第三届ACM大学生程序设计竞赛]——n a^o7 !
n a^o7 ! 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2413 Time Lim ...
- angry_birds_again_and_again(2014年山东省第五届ACM大学生程序设计竞赛A题)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2877 题目描述 The problems ca ...
- [2012山东省第三届ACM大学生程序设计竞赛]——Mine Number
Mine Number 题目:http://acm.sdut.edu.cn/sdutoj/problem.php? action=showproblem&problemid=2410 Time ...
随机推荐
- java 面向对象编程--第17章 I/O系统
1.I/O操作指的是输入和输出流的操作.相对内存而言,当我们从数据源中将数据读取到内存中,就是输入流,也叫读取流.当我们将内存中处理好的数据写入数据源,就是输出流,也叫写入流. 2.流按照内容分类:字 ...
- 绑定本地Service并与之通信-----之二
import android.os.Bundle;import android.os.IBinder;import android.app.Activity;import android.app.Se ...
- Time, Clocks, and the Ordering of Events in a Distributed System
作者:Leslie Lamport(非常厉害的老头了) 在使用消息进行通信的分布式系统中,使用物理时钟对不同process进行时间同步与事件排序是非常困难的.一是因为不同process的时钟有差异,另 ...
- 百度上传android包:应用名解析失败!
manifest 里面<application增加android:label="@string/app_name"
- ubnutu安装sougou 输入法
先安百度经验安装fcitx 1.首先下载sogoupinyin_2.0.0.0068_amd64.deb,点击安装后,会通过ubuntu软件中心安装,安装玩成后,任然是无法使用.然后: 2.然后执行下 ...
- svn自动更新
果对svn不熟悉,当svn上面有更新时,想看到实时效果,就得去web目录手动更新,比较麻烦 其它svn有一个自动更新的功能 利用 hook 在svn 仓库目录下面有一个hook目录 在post-c ...
- android自定义控件实例(Linearlayout组合TextView和ImageView)
2013-12-18 11:25:22 转载自: http://www.open-open.com/lib/view/open1328836804515.html 很多时候android常用的控件不能 ...
- poj1274 二分匹配
今天复习二分匹配,A 了一道模板题. 二分匹配需要理解增广路的寻找.用dfs来更新最大匹配.注意一些点:赋初值:愚蠢地把==写成了= ; 然后match的记值;每个点都要重新走一遍. #include ...
- string.format
string.Format("{0:#,0}", c.num), //千分号,有小数就保留2位小数 string.Format("{0:N2}", c.amou ...
- 如何对Linux的grub进行加密
一.加密 设置grub密码: 众所周知,通过编辑GRUB启动参数可以轻松的进入单用户模式从而修改root密码,这对于一台多用户的计算机或服务器来说,无疑增加了安全隐患.大家一定很像为自己的GRUB加一 ...