Codeforce 220 div2
D
插入: 在当前指针位置sz处插入一个1,col[sz]记录插入的内容,sz++;
删除i: 找到第i个1的位置,赋为0;
于是转化为一个维护区间和的问题;
trick:
如果是依次删除a[0],a[1]...a[k], 那么对应的删除操作应该为 a[0],a[1]-1,a[2]-2...a[k]-k,要把前面删掉的算进去;
#define maxn 1000100
int bit[maxn],a[maxn],n,m,col[maxn],sz;
int lowbit(int x){return x&(-x);}
void ins(int pos,int c,int v){
col[pos]=c;
// printf("ins %d at %d c=%d\n",v,pos,c);
for (int cur=pos ; cur<=n ; cur+=lowbit(cur))
bit[cur]+=v;
}
int query(int x){
int res=;
for (int i=x ; i> ; i-=lowbit(i)) res += bit[i];
return res;
}
int sum(int l,int r){
return query(r)-query(l-);
}
void del(int pos){
int l=,r=sz;
while (l<r){
if(query(mid)>=pos) r=mid;
else l=mid+;
}
// printf("del:%dth at %d\n",pos,l);
ins(l,col[l],-);
}
int binsearch(int l,int r,int len){
while (l<=r){
if (a[mid]>len) r=mid-;
else l=mid;
if (l+>=r){
if (a[r]<=len) return r;
if (a[l]<=len) return l;
return -;
}
}
return -;
}
int main(){
// freopen("test","r",stdin);
scanf("%d%d",&n,&m);
rep(i,m) scanf("%d",&a[i]);
sz = ;
rep(i,n){
int o;
scanf("%d",&o);
// printf("o=%d\n",o);
if (o==-){
int len = sum(,sz);
int k = binsearch(,m-,len);
// printf("len=%d k=%d\n",len,k);
for (int i= ; i<=k ; i++ ) del(a[i]-i);
}else{
ins(++sz,o,);
}
}
if (query(sz)){
for (int i= ; i<=sz ; i++ ) if(sum(i,i)) printf("%d",col[i]);
}
else
printf("Poor stack!\n");
return ;
}
E
显然把坐标变为(x+y,x-y),生长的线段都是平行坐标轴的,会让问题简单很多;
然后考虑某时间t,有若干线段,如果能判断这些线段是否构成矩形,就能二分t来确定答案;
判断:
预处理处当前时间产生的所有线段;
枚举横线作为矩形上边,将所有与它相交的竖线插入树状数组,
枚举,下边,回答询问,>=2说明围成矩形;
这是O(n^3)做法,可以通过排序,逐个插入等办法优化成O(n^2)的.
#define rep(i,n) for(int i=0 ; i<(n) ; i++)
#define mid ((l+r)>>1)
#define ls ((rt<<1))
#define rs ((rt<<1)+1)
#define maxn 2020
#define INF 2000100
struct node{
int x,y;
};node red[maxn],blue[maxn];
struct line{
int p,l,r;
};vector<line>lx[maxn],ly; int n,m,bit[maxn][maxn];
vector<int>X,Y;
bool cmpb(node a,node b){
return (a.x==b.x)?(a.y<b.y):(a.x<b.x);
}
bool cmpr(node a,node b){
return (a.y==b.y)?(a.x<b.x):(a.y<b.y);
}
void input(){
scanf("%d%d",&n,&m);
int x,y;
rep(i,n) {
scanf("%d%d",&x,&y);
blue[i]=(node){x+y,x-y};
X.push_back(blue[i].x);
}
rep(i,m) {
scanf("%d%d",&x,&y);
red[i]=(node){x+y,x-y};
Y.push_back(red[i].y);
}
sort(blue,blue+n,cmpb);
sort(red,red+m,cmpr);
}
void compress(){
sort(X.begin(),X.end());
sort(Y.begin(),Y.end());
X.erase(unique(X.begin(),X.end()),X.end());
Y.erase(unique(Y.begin(),Y.end()),Y.end());
}
int findlft(vector<int>a,int var){
int l=,r=(int)a.size()-;
while (l<r){
if (a[mid]>=var) r=mid;
else l=mid+;
}
return a[l]>=var?l:INF;
}
int findrgt(vector<int>a,int var){
int l=,r=(int)a.size()-;
while (l<=r){
if (a[mid]<=var) l=mid;
else r=mid-;
if (l+>=r){
if (a[r]<=var) return r;
if (a[l]<=var) return l;
return -INF;
}
}
return -INF;
}
int lowbit(int x) {return x&(-x);}
int query(int y,int x){
int res=;
for ( ; x> ; x-=lowbit(x)) {
res += bit[y][x];
if (bit[y][x]<) while();
}
return res;
}
int sum(int y,int l,int r){
if (l>r) return ;
return query(y,r)-query(y,l-);
}
void ins(int y,int x,int v){
for ( ; x<maxn ; x+=lowbit(x) ) {
bit[y][x]+=v;
if (bit[y][x]<) while();
}
}
bool vis[maxn];
void addline(int idx){
for (int i=ly[idx].l ; i<=ly[idx].r ; i++ )
ins(i,ly[idx].p,);
vis[idx]=true;
}
void delline(int idx){
for (int i=ly[idx].l ; i<=ly[idx].r ; i++ )
ins(i,ly[idx].p,-);
vis[idx]=false;
}
bool check(int t){
ly.clear();
rep(i,(int)Y.size()) lx[i].clear();
rep(i,n){//find ly;
int x = lower_bound(X.begin(),X.end(),blue[i].x)-X.begin()+;
int l = blue[i].y-*t;
int r = blue[i].y+*t;
while (i+<n){
int tmp = blue[i+].y-*t;
if (blue[i+].x==blue[i].x && l<=tmp && tmp<=r){
r = blue[i+].y+*t;
i++;
}else break;
}
l = findlft(Y,l);
r = findrgt(Y,r);
if (l<=r) ly.push_back((line){x,l,r});
}
rep(i,m){//find lx;
int y = lower_bound(Y.begin(),Y.end(),red[i].y)-Y.begin();
int l = red[i].x-*t;
int r = red[i].x+*t;
while (i+<m){
int tmp = red[i+].x-*t;
if (red[i+].y==red[i].y && l<=tmp && tmp<=r){
r = red[i+].x+*t;
i++;
}else break;
}
l = findlft(X,l)+;
r = findrgt(X,r)+;
if (l<r) lx[y].push_back((line){y,l,r});
}
rep(i,(int)Y.size()){
rep(j,(int)ly.size()) if (vis[j] && !(ly[j].l<=i && i<=ly[j].r)) delline(j);
rep(j,(int)ly.size()) if (!vis[j] && ly[j].l<=i && i<=ly[j].r) addline(j); rep(j,(int)lx[i].size()){
line cur = lx[i][j];
if (sum(i,cur.l,cur.r)<) continue;
rep(k,i) rep(x,(int)lx[k].size()){
int l = max(cur.l,lx[k][x].l);
int r = min(cur.r,lx[k][x].r);
if (sum(i,l,r)>= && sum(k,l,r)>=) {
rep(i,(int)ly.size()) if(vis[i]) delline(i);
return true;
}
}
}
}
rep(i,(int)ly.size()) if(vis[i]) delline(i);
return false;
}
int binsearch(int l,int r){
while (l<r){
if (check(mid)) r=mid;
else l=mid+;
}
return check(l)?l:;
}
int main(){
// freopen("test","r",stdin);
input();
compress();
int ans = binsearch(,INF);
if (!ans) printf("Poor Sereja!\n");
else printf("%d\n",ans);
return ;
}
Codeforce 220 div2的更多相关文章
- 220 DIV2 B. Inna and Nine
220 DIV2 B. Inna and Nine input 369727 output 2 input 123456789987654321 output 1 题意:比如例子1:369727--& ...
- Codeforce Round #220 Div2
这场气场太大,居然一个题不会! 所以没交! 赛后发现 A:陷阱多- -!不要超过上下界,可以上去再下来! B:不会做! C:自己想太多- -!
- codeforce 192 div2解题报告
今天大家一起做的div2,怎么说呢,前三题有点坑,好多特判.... A. Cakeminator 题目的意思是说,让你吃掉cake,并且是一行或者一列下去,但是必须没有草莓的存在.这道题目,就是判断一 ...
- Codeforce 287 div2 C题
题目链接:http://codeforces.com/contest/507/problem/C 解题报告:现在有一个满二叉树型的迷宫,入口在根结点,出口在第n个叶节点,有一串命令,LRLRLRLRL ...
- 220 DIV2 A. Inna and Pink Pony
Inna and Pink Pony 输入n,m,i,j,a,b 可以看成n行m列的矩阵,起点(i,j),每次移动(a,b),(-a,-b),(-a,b),(a,-b) 可移动到(1,m),(n,1) ...
- codeforce #339(div2)C Peter and Snow Blower
Peter and Snow Blower 题意:有n(3 <= n <= 100 000)个点的一个多边形,这个多边形绕一个顶点转动,问扫过的面积为多少? 思路:开始就认为是一个凸包的问 ...
- Codeforce 218 div2
D 一开始想错了,试图用"前缀和-容量"来求从上层流下来了多少水",但这是错的,因为溢出可能发生在中间. 然后发现对于每层,溢出事件只会发生一次,所以可以用类似并查集的办 ...
- Codeforce 217 div2
C 假设每种颜色的个数都相同,可以用轮换的方式,让答案达到最大n,当不同的时候,可以每次从每种颜色中取出相同个数的手套来操作; 一直迭代下去直到只剩下1种颜色; 再将这一种颜色与之前交换过的交换就行了 ...
- Codeforce 216 div2
D 只要搞清楚一个性质:确定了当前最大和次大的位置,局面就唯一确定了; 根据这个性质设计dp,统计到达该局面的方法数即可. E 询问的要求是: 求有多少个区间至少覆盖了询问的点集中的一个; 转化成逆命 ...
随机推荐
- animate.min.css 动画样式移动端存在的问题
使用animate.min.css可以使用很多动画效果,包括3D效果,现在也可以应用于HTML5手机移动端,使用切换效果的时候会导致页面出现卡顿现象,可以使用css3 transform 方法硬件加速 ...
- HybridApp开发准备工作——WebView
如大家所见,手机真是越来越离不开我们的日常生活了,像我,现在出门必带的是手机.移动电源.公交卡:钱包什么的再也没出过门.两年前,我还在Android的应用开发中当了一次过客.嗯,当时JAVA学得太糟糕 ...
- [置顶] ARM指令集和常用寄存器
1) ARM指令集 32位的 ARM指令和 16位 的Thumb指令 1,寄存器寻址 MOV R1, R2 //将寄存器R2的值传给寄存器R1 2,立即寻址 MOV R0, #0XFF00 //数据 ...
- Java基础知识强化32:String类之String类的判断功能
1. String类的判断功能: boolean equals (Object obj ) boolean equalsIgnoreCase (String str ) boolean contain ...
- CentOS LiveCD LiveDVD DVD 等版本的区别
1.CentOS系统镜像DVD有两个,安装系统只用到第一个镜像即CentOS-6.7-x86_64-bin-DVD1.iso,第二个镜像CentOS-6.7-x86_64-bin-DVD2.iso是系 ...
- CentOS NFS的安装配置、启动及mount挂载方法
一.环境介绍: 服务器:centos 192.168.1.225 客户端:centos 192.168.1.226 二.安装: NFS的安装配置:centos 5 : yum -y install n ...
- SQL每个用户最后的一条记录
SELECT [ID] ,[UserID] ,[StartDate] ,[EndDate] ,[CreateUser] ,[CreateDate] ,[LastEditUser] ,[LastEdit ...
- canvas.toDataURL(type, args)
canvas.toDataURL(type, args)该方法能够将canvas转换为图像,图像是基于Base64编码的.如果不指定两个参数,无参数调用该方法,转换的图像格式为png格式 •type: ...
- Path对象
Path是连续的Segment的集合,除了 Path 的第一个Segment和最后一个Segment外,其余的Segment的起始点都是前一个Segment的终止点,即Path对象的中的Segment ...
- Enumeration
Interface Enumeration<E> hasMoreElements() boolean hasMoreElements() 仅当此枚举对象包含至少一个以上元素为真:否则 ...