[POI2007]EGZ-Driving Exam
能到达所有路的充要条件是能到达左右两端的路
用vector反向建边对每条路左右分别求个最长不上升子序列
预处理出每条路向左向右分别需要多建多少路才能到达最左端和最右端
然后跑个\(\Theta(n)\)的尺取法就可以了
本题最长不上升子序列用vector+zkw线段树比二分更加好想?
原来标程的solve函数尺取时出锅(但是居然AC了
感谢我自己回来看题解发现看不懂
现在这题解是真题解了
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"vector"
using namespace std;
const int MAXN=1<<17;
int n,m,P,K,np;
int f[2][MAXN];
int tree[MAXN<<1];
struct rpg{bool kd;int h,fl,fr;};
vector<rpg> vec[MAXN];
int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return x;
}
void calcl()
{
for(int i=1;i<n;++i){
for(int j=0;j<vec[i].size();++j){
if(!vec[i][j].kd){
int l=MAXN+vec[i][j].h-1,r=MAXN+m+2,maxn=0;
while(l^r^1){
if(~l&1) maxn=max(maxn,tree[l^1]);
if(r&1) maxn=max(maxn,tree[r^1]);
l>>=1;r>>=1;
}vec[i][j].fl=maxn+1;
}
}for(int j=0;j<vec[i].size();++j){
if(!vec[i][j].kd){
for(int k=MAXN+vec[i][j].h;k;k>>=1){
tree[k]=max(tree[k],vec[i][j].fl);
}
}
}int l=MAXN,r=MAXN+m+2,maxn=0;
while(l^r^1){
if(~l&1) maxn=max(maxn,tree[l^1]);
if(r&1) maxn=max(maxn,tree[r&1]);
l>>=1,r>>=1;
}f[0][i+1]=maxn;
}return;
}
void calcr()
{
for(int i=n;i>1;--i){
for(int j=0;j<vec[i].size();++j){
if(vec[i][j].kd){
int l=MAXN+vec[i][j].h-1,r=MAXN+m+2,maxn=0;
while(l^r^1){
if(~l&1) maxn=max(maxn,tree[l^1]);
if(r&1) maxn=max(maxn,tree[r^1]);
l>>=1;r>>=1;
}vec[i][j].fr=maxn+1;
}
}for(int j=0;j<vec[i].size();++j){
if(vec[i][j].kd){
for(int k=MAXN+vec[i][j].h;k;k>>=1){
tree[k]=max(tree[k],vec[i][j].fr);
}
}
}int l=MAXN,r=MAXN+m+2,maxn=0;
while(l^r^1){
if(~l&1) maxn=max(maxn,tree[l^1]);
if(r&1) maxn=max(maxn,tree[r&1]);
l>>=1,r>>=1;
}f[1][i-1]=maxn;
}return;
}
void init()
{
n=read(),m=read(),P=read(),K=read();
for(int i=1;i<=P;++i){
int x=read(),y=read(),z=read();
if(z) vec[x].push_back((rpg){z^1,y+1});
else vec[x+1].push_back((rpg){z^1,y+1});
}calcl();memset(tree,0,sizeof(tree));calcr();
for(int i=1;i<=n;++i) f[0][i]=i-f[0][i]-1,f[1][i]=n-i-f[1][i];
return;
}
void solve()
{
int ans=0,ct=0,cnt=0;
for(int i=1;i<=n;++i){
while(ct+1<=n&&f[1][i]+f[0][ct+1]<=K){
++ct;
if(!f[0][ct]&&!f[1][ct]) ++cnt;
}ans=max(ans,ct-i+1-cnt);
if(!f[0][i]&&!f[1][i]) --cnt;
}printf("%d\n",ans);
return;
}
int main()
{
init();
solve();
return 0;
}
[POI2007]EGZ-Driving Exam的更多相关文章
- 解题:POI 2007 Driving Exam
题面 有点意思的题 从一个位置$i$出发可以到达每一个位置即是从$1,n$出发可以到达$i$.然后有了一个做法:把图上下反转后建反图,这样就可以求从一个点$i$到达左右两侧的花费$dp[i][0/1] ...
- BZOJ 1107: [POI2007]驾驶考试egz / Luogu P3463 [POI2007]EGZ-Driving Exam (树状数组 LIS)
能从iii走到所有跑道 相当于 能从iii走到111和nnn. 边反向后就相当于 能从111和nnn走到iii. 为了方便叙述,把111~nnn叫做x坐标,111~(m+1)(m+1)(m+1)叫做y ...
- BZOJ1107 : [POI2007]驾驶考试egz
i可以作为起点说明把边反向后可以从1和n到达i. 设fl[i]表示从1到达i至少需要加几条边,fr[i]表示从n到达i至少需要加几条边. 把图上下翻转后,从左往右依次计算fl[i],有fl[i]=i- ...
- [POI2007]驾驶考试egz
题目 BZOJ 神仙题,可比那些氵紫题有意思多了 做法 \(i\)能作为起始点,当\(i\)能到达\(1\)~\(i-1\)和\(i+1\)~\(n\) 这样处理显然会麻烦,因为要从每个点都特判一次 ...
- HDU 2633 Getting Driving License(模拟)
Getting Driving License Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
- Linux学习之Exam系统发布
配置时间:2015年11月27日 配置人:撰写人:微冷的雨 Happy 01.Linux安装图 欢迎页面 桌面 02.Linux命令之文件目录操作 给北大青鸟五道口校区创建三个机房(L4,L5,L ...
- BZOJ1098: [POI2007]办公楼biu
从问题可以看出是求补图的连通块及点数 但补图太大.所以考虑缩小规模. 当一个点归属于一个连通块后,它以后就不需要了.所以可以用链表,删去这个点,也就减小了规模. 一个点开始bfs,每个点只会进队一次, ...
- BZOJ1097: [POI2007]旅游景点atr
..k次最短路后,考虑如何满足先走一些点 用状压dp,每一个点考虑它所需要经过的点a[i],当当前走过的点包含a[i]时,i 这个点才可以到达. 写的时候用记忆化搜索. #include<bit ...
随机推荐
- day 08 课后作业
# -*- coding: utf-8 -*-# @Time : 2018/12/27 17:27# @Author : Endless-cloud# @Site : # @File : day 8课 ...
- 编程开发之--java多线程学习总结(1)问题引入与概念叙述
1.经典问题,火车站售票,公共票源箱,多个窗口同时取箱中车票销售 package com.lfy.ThreadsSynchronize; /** * 解决办法分析:即我们不能同时让超过两个以上的线程进 ...
- js对象注意
var obj = {}; //定义一个对象 obj[1] = 1; //设置obj对象的属性为数字1属性,属性值为1 obj['1'] = 2398; //设置obj对象的属性为字符串1属性,属性值 ...
- logrotate运行时间指定
Edit in /etc/crontab the line that says 25 6 * * * root test -x /usr/sbin/anacron || ( cd / &&am ...
- Angular Material 按钮图标系列
工做中经常用到Angular Material 中的好多按钮素材,奈何官网经常上不去,所以只能自己把这些常用的按钮扒下来了,留给自己同时也留给大家方便查看. Angular material mat- ...
- SqlServer索引、优化、约束、连接
索引的创建和删除 create index in_name on person(name) --创建索引 drop index person.in_name --删除索引 create index i ...
- python 进程与线程(理论部分)
一.理论部分 一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的 ...
- 《python灰帽子》学习笔记:写一个windos 调试器(一)
一.开发内容介绍 为了对一个进程进行调试,你首先必须用一些方法把调试器和进程连接起来.所以, 我们的调试器要不然就是装载一个可执行程序然后运行它, 要不然就是动态的附加到一个运行的进程.Windows ...
- 利用keepalived构建高可用MySQL-HA
关于MySQL-HA,目前有多种解决方案,比如heartbeat.drbd.mmm.共享存储,但是它们各有优缺点.heartbeat.drbd配置较为复杂,需要自己写脚本才能实现MySQL自动切换,对 ...
- redis实战笔记(1)-第1章 初识Redis
第1章 初识Redis 注:本书在redis3.0版本的,比如redis3.0以后支持服务端集群.3.0之前只能客户端分片. 本章主要内容 1.Redis与其他软件的相同之处和不同之处 2.Re ...