P3696,玄妙的贪心题
来源:互联网 发布:ubuntu 16.10 更新源 编辑:程序博客网 时间:2024/06/13 22:24
首先把中场的每个团体看做左括号。结束时的每个团体看做右括号。然后按照人气值从小到大排序(实际上因为初始输入就有序,可以用归并来代替排序)。
这样我们就得到了一个括号序列。每个括号都有一个颜色(即其学校编号)。然后要删掉尽量多的同色括号对,并使得剩下的括号序列仍然合法。
从左往右考虑每个括号,一开始花了一个下午想了五种
一个无所作为的下午告诉我,
将左括号视为1,右括号视为-1,那么一个合法的括号序列,其所有前缀和一定非负。
考虑删掉一对括号对前缀和的影响,这相当于对前缀和区间减。
然而要保证前缀和非负,所以减的区间中,最小值要大于零。
考虑一个右括号能否找到与之匹配,且一起删掉后合法的左括号。记ss
为这个右括号以左第一个为零的前缀和所在的位置,那么左括号一定要在那个位置以右,并且二者同色。
用线段树实现区间加和区间最小值,查询ss
时二分,就得到了优越拙劣的
另外说一句,这道题里票数可以为零,这,坑了我很久,甚至对拍也拍不出。以后还是要注意,这个错误把我坑到45分(其中25分是常数太大)
#include<cstdio>#include<cctype>#include<vector>const int N=400010,L=1000000;char ibuf[L],*ih=ibuf+L;inline char gc(){return ih==ibuf+L?fread(ibuf,1,L,stdin),ih=ibuf,*ih++:*ih++;}inline void read(int&x){ static char c; for(c=gc();!isdigit(c);c=gc()); for(x=0;isdigit(c);c=gc())x=x*10+c-48;}std::vector<int> s[N];int n,i,j,ans,ss,aa[N],bb[N],xb,ea[N],eb[N],l,r,m;struct person{int x,y;}a[N],b[N];inline int min(int a,int b){return a>b?b:a;}struct segtree{ struct node{ int l,r,m,s,mn; }t[N<<2]; void build(int i,int l,int r){ t[i].l=l,t[i].r=r;t[i].m=(l+r)>>1; if(l==r)return;build(i<<1,l,t[i].m),build(i<<1|1,t[i].m+1,r); } inline void add(int i,int l,int r,int v){ if(t[i].l==l && t[i].r==r)t[i].s+=v,t[i].mn+=v; else{ if(t[i].m<l)add(i<<1|1,l,r,v); else if(r<=t[i].m)add(i<<1,l,r,v); else add(i<<1,l,t[i].m,v),add(i<<1|1,t[i].m+1,r,v); t[i].mn=(t[i<<1].mn>t[i<<1|1].mn?t[i<<1|1].mn:t[i<<1].mn)+t[i].s; } } inline int query(int i,int l,int r){ if(t[i].l==l && t[i].r==r)return t[i].mn; return (r<=t[i].m?query(i<<1,l,r):(l>t[i].m?query(i<<1|1,l,r):min(query(i<<1,l,t[i].m), query(i<<1|1,t[i].m+1,r))))+t[i].s; }}t;int main(){ read(n);ans=n;t.build(1,1,n<<1); for(i=1;i<=n;++i)read(a[i].x),read(a[i].y); for(i=1;i<=n;++i)read(b[i].x),read(b[i].y);s[b[1].x].push_back(1);aa[xb=1]=1;bb[1]=1; t.add(1,1,n<<1,1);eb[1]=1;b[n+1].y=-1; for(i=j=1;i<=n;++i){ while(b[j+1].y>=a[i].y)++j,aa[eb[j]=++xb]=j,s[b[j].x].push_back(xb),bb[xb]=1, t.add(1,xb,n<<1,1); aa[ea[i]=++xb]=i,bb[xb]=-1;t.add(1,xb,n<<1,-1); for(l=ss,r=xb-1;l<r;){ m=(l+r+1)>>1; if(t.query(1,m,xb-1))r=m-1; else l=m; } ss=l; if(!s[a[i].x].empty() && s[a[i].x].back()>ss)--ans,t.add(1,s[a[i].x].back(),ea[i]-1,-1), s[a[i].x].pop_back(); } printf("%d\n",ans); return 0;}
阅读全文
0 0
- P3696,玄妙的贪心题
- 玄妙的设计模式
- 玄妙的设计模式
- 老子“有”与“无”的玄妙论
- 第8章 玄妙的物理——物理建模与粒子系统初步
- 两道坑爹的贪心题
- 简单的贪心题 c
- 贪心题:萌萌哒的GG
- 贪心的一道题 Supermarket
- 最近在探讨关于缓冲区溢出的相关问题,各位大侠帮忙看看这个程序,两个for循环导致内存内容不一样,其中的玄妙在哪里?我是嫩草,谢啦谢啦~~
- 一道无语的贪心题......
- 贪心思想题的解题报告
- Radar Installation (贪心+数学 不错的题 )
- 第十二题 任务调度的贪心
- [贪心] 关于贪心的实例的实现
- 贪心好题(两种变量的贪心)poj3262 Protecting the Flowers
- 【贪心】拟阵论 贪心策略的数学基础
- 贪心算法的详解
- 【分治法】折半查找及C++代码实现
- 动态规划总结
- Linux安装JDK
- log4j.properties 详解与配置步骤
- 【水】背包问题的POJ例题
- P3696,玄妙的贪心题
- Android自定义标题+画圆+进度条
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
- Java NIO:浅析I/O模型
- Android自带的toolbox分析及扩展
- 【poj 1502】 MPI Maelstrom 【East Central North America 1996】
- Travel HDU
- Can't create handler inside thread that has not called Looper.prepare()
- 数学计算模拟类问题:加法,除法和幂,注意越界问题。题 剑指Offer,Pow(x, n) ,Divide Two Integers