CF#310-E - Case of Chocolate-(set+贪心)/(线段树+离散化)/(隐式线段树)
来源:互联网 发布:汉邦网络摄像机默认ip 编辑:程序博客网 时间:2024/06/14 03:58
看了官解 是用2个线段树,一个维护横坐标,一个维护纵坐标(要离散化).......还有后面的隐式线段树还没看
后来看到另一种方法、仔细分析下题目的操作,其实很简单。
用两个set维护 横纵坐标、分别叫row(水平方向)、high(竖直)
分析两种情况:
对于(xi,n+1-xi),若是向上吃,能够影响它的操作(xj,n+1-xj)一定是右边第一个点,
若点i右边有点:
如果点j为向上吃,如果j能吃到x=0处,则表示点i和j之间无L操作,则点i也吃到x=0
如果点j为向上吃,但是只吃到x=b处,则表示点i和j都会被一操作L(x=b-1)截断,所以点i也吃到x=b;
如果点j为向左吃(吃到x=b),那么只有一种情况, 点i会被j截断,点i吃到x=b+1处
若点i右边无点:
点i吃到0处;
对于向左的(xi,n+1-xi),能够影响它的操作(xj,n+1-xj)一定是左边第一个点,
如果点i左边有点:
如果点j为向左吃,如果j能吃到x=0处,则表示点i和j之间无U操作,则点i也吃到x=0
如果点j为向左吃,但是只吃到r=a处,则表示点i和j都会被一操作u(r=a-1)截断,所以点i也吃到r=a;
若点i左边无点:
点i吃到0处;
然后就是实现了,注意,如果某个坐标已经出现过了,再次出现吃的巧克力数量为0;
特别要注意的是 在各个情况下 对begin和end的判断,否则容易指针越界
--------------------------
UPDATA:发现很多情况都可以合并在一起,只用一个set维护即可,每次判断是否存在第一个r坐标大于等于点i的点j即可,如果存在,必定受其影响,不存在,必定吃到边界结束;
代码:
#include <cstdio>#include <cmath>#include <iostream>#include <set>#include <algorithm>using namespace std;struct node{int r,c;int last;char ty;node(){}node(int a,int b,int cc,char t){r=a;c=b;last=cc;ty=t;}bool operator <(const node&b)const{return r<b.r;}bool operator ==(const node&b)const{return r==b.r&&c==b.c;}};int cmp(node a,node b){return a.r>b.r;}set<node> sb;set<node>::iterator it;int main(){int i,j;int n,m;int a,b;char op;scanf("%d%d",&n,&m);for (i=1;i<=m;i++){node tp;scanf("%d %d %c",&a,&b,&op);if (op=='U'){tp.r=a;it=sb.lower_bound(tp); if (it->r==a){printf("0\n");}elseif (it==sb.end()){sb.insert(node(a,b,1,op));printf("%d\n",b);}else{if (it->ty=='U'){//printf("%d\n",it->last);sb.insert(node(a,b,it->last,op));printf("%d\n",b-it->last+1);}else{sb.insert(node(a,b,it->c+1,op));printf("%d\n",b-it->c); } } }else{tp.r=a;it=sb.lower_bound(tp);if (it->r==a){printf("0\n");}elseif (it==sb.begin()){sb.insert(node(a,b,1,op));printf("%d\n",a);}else{it--;if (it->ty=='L'){sb.insert(node(a,b,it->last,op));printf("%d\n",a-it->last+1);}else{sb.insert(node(a,b,it->r+1,op));printf("%d\n",a-it->r); } }}}return 0;}
-------------------------
以下是上一种方法的写法:
#include <cstdio>#include <cmath>#include <iostream>#include <set>#include <algorithm>using namespace std;struct node{int r,c;int last;node(){}node(int a,int b,int cc){r=a;c=b;last=cc;}bool operator <(const node&b)const{return r<b.r;}bool operator ==(const node&b)const{return r==b.r&&c==b.c;}};int cmp(node a,node b){return a.r>b.r;}set<node> row;set<node> high;set<node>::iterator it,nx;int main(){int i,j;int n,m;int a,b;char op;scanf("%d%d",&n,&m);for (i=1;i<=m;i++){node tp;scanf("%d %d %c",&a,&b,&op);if (op=='U'){ if (high.find(node(a,b,0))!=high.end()||row.find(node(a,b,0))!=row.end()){ printf("0\n"); continue;}tp.r=a;it=row.lower_bound(tp);nx=high.lower_bound(tp);if ( nx==high.end())//如果有不存在L操作在点i的右边,那么必定可以吃到0为止{ row.insert(node(a,b,0));printf("%d\n",b);}else//以下情况必定点i右边有L操作{int not1=0; if (it==row.end())//右边有L时,如果it==end,也就是点i右边不存在U操作,所以一定被L操作截断 not1=1; if (not1||(nx->r<it->r))//如果既有U也有L,但是L操作比较靠近点i, 点i一定被L操作截断{//printf("%d\n",nx->c);row.insert(node(a,b,nx->c+1));printf("%d\n",b-nx->c);}else//如果既有U也有L,但是U操作比较靠近点i, 点i能吃到最远处与该u操作一样远if (nx->r>it->r){if (it->last==0){row.insert(node(a,b,0));printf("%d\n",b);}else{row.insert(node(a,b,it->last));printf("%d\n",b-it->last+1);}}}}else // 'L'{if (high.find(node(a,b,0))!=high.end()||row.find(node(a,b,0))!=row.end()){printf("0\n"); continue;} tp.r=a;it=high.lower_bound(tp);nx=row.lower_bound(tp); if (nx==row.begin())//如果U操作全在点i的右边,那么点i的L操作必然能吃到0;{ high.insert(node(a,b,0));printf("%d\n",a);}else//以下情况必定点i左边有U操作{ int not1=0; if (it==high.begin())//左边有U时,如果it==begin,也就是点i左边不存在L操作,所以一定被U操作截断 not1=1;elseit--; nx--;//lowerbound得到的是大于等于的第一个,所以要nx--得到小于的第一个if (not1||(nx->r>it->r ) )//如果既有U也有L,但是U操作比较靠近点i, 点i一定被U操作截断{//printf("%d\n",nx->r);high.insert(node(a,b,nx->r+1));printf("%d\n",a-nx->r);}else//如果既有U也有L,但是L操作比较靠近点i, 点i能吃到最远处与该L操作一样远if ( nx->r<it->r ){if (it->last==0){high.insert(node(a,b,0));printf("%d\n",a);}else{high.insert(node(a,b,it->last));printf("%d\n",a-it->last+1);}}}}}return 0;}
- CF#310-E - Case of Chocolate-(set+贪心)/(线段树+离散化)/(隐式线段树)
- 离散化+线段树 codefores555C Case of Chocolate
- 线段树 Case of Chocolate:CodeForces
- cf #310 E. Case of Chocolate (upper_bound())
- Codeforces Round #310 (Div. 1) C. Case of Chocolate (线段树)
- cf 474E 线段树+dp+离散化后二分查找
- CF 558E 线段树
- CF 19D 线段树+set压缩坐标轴+离散化map
- 线段树+离散化
- 离散化 + 线段树
- 线段树离散化
- 线段树离散化
- cf 219E parking lot 线段树
- CF 338E Optimize! (线段树)
- CF E. Enemy is weak 线段树
- [CF 338E] Optimize! · 线段树
- CF 338E Optimize! (线段树)
- codeforces 271E 离散化+线段树,dp优化
- 学习笔记 - java FileWriter对文本文件的写入
- 样式浅谈2
- hibernate开发几个提示!
- Google C++ Style Guide的哲学
- QT5 学习之路04---QT5基本对话框1
- CF#310-E - Case of Chocolate-(set+贪心)/(线段树+离散化)/(隐式线段树)
- 循环和递归的异同
- 12硬币中有一个不知道轻重的假币,用天平将它找出来
- OneNote 2013 快捷键
- java基础之集合框架——Collections-同步和非同步
- Shader入门指南【2】
- iCloud De-duplication
- HashSet的对象必须实现hashCode()和equals()
- Chromium硬件加速渲染机制基础知识简要介绍和学习计划