能到达所有路的充要条件是能到达左右两端的路

用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的更多相关文章

  1. 解题:POI 2007 Driving Exam

    题面 有点意思的题 从一个位置$i$出发可以到达每一个位置即是从$1,n$出发可以到达$i$.然后有了一个做法:把图上下反转后建反图,这样就可以求从一个点$i$到达左右两侧的花费$dp[i][0/1] ...

  2. 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 ...

  3. BZOJ1107 : [POI2007]驾驶考试egz

    i可以作为起点说明把边反向后可以从1和n到达i. 设fl[i]表示从1到达i至少需要加几条边,fr[i]表示从n到达i至少需要加几条边. 把图上下翻转后,从左往右依次计算fl[i],有fl[i]=i- ...

  4. [POI2007]驾驶考试egz

    题目 BZOJ 神仙题,可比那些氵紫题有意思多了 做法 \(i\)能作为起始点,当\(i\)能到达\(1\)~\(i-1\)和\(i+1\)~\(n\) 这样处理显然会麻烦,因为要从每个点都特判一次 ...

  5. HDU 2633 Getting Driving License(模拟)

    Getting Driving License Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  6. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

  7. Linux学习之Exam系统发布

    配置时间:2015年11月27日 配置人:撰写人:微冷的雨   Happy 01.Linux安装图 欢迎页面 桌面 02.Linux命令之文件目录操作 给北大青鸟五道口校区创建三个机房(L4,L5,L ...

  8. BZOJ1098: [POI2007]办公楼biu

    从问题可以看出是求补图的连通块及点数 但补图太大.所以考虑缩小规模. 当一个点归属于一个连通块后,它以后就不需要了.所以可以用链表,删去这个点,也就减小了规模. 一个点开始bfs,每个点只会进队一次, ...

  9. BZOJ1097: [POI2007]旅游景点atr

    ..k次最短路后,考虑如何满足先走一些点 用状压dp,每一个点考虑它所需要经过的点a[i],当当前走过的点包含a[i]时,i 这个点才可以到达. 写的时候用记忆化搜索. #include<bit ...

随机推荐

  1. Linux(Ubuntu)新建用户只有一个$问题

    参考自: http://www.cnblogs.com/ylan2009/articles/2321177.html 1.用root登录操作 2.查看/etc/passwd文件中新建用户的权限 有没有 ...

  2. Linux之Ubuntu中的安装应用

    在Ubuntu中我们经常会使用apt install “APP name” 来安装需要的应用. 从图中我们可以看到,我们使用apt install map命令安装一个map小游戏,这个小游戏是一个用四 ...

  3. 初始linux系统--ubuntu

    ubuntu操作系统  1. Linux系统组成 Linux内核软件程序用于实现CPU和内存分配进程调度设备驱动等核心操作,以面向硬件为主 外围程序面向用户为主,包括分析用户指令的解释器网络服务程序图 ...

  4. follow up2-20190426

    406. Minimum Size Subarray 同向双指针 https://www.lintcode.com/problem/minimum-size-subarray-sum/descript ...

  5. LINQ入门教程之各种标准查询操作符(一)

    好久之前就想系统的学习下LINQ,好久之前…… 本篇文章主要介绍LINQ等的标准查询操作符,内容取自<LINQ高级编程>,后续还会介绍LINQ to XML ,LINQ to SQL. L ...

  6. java翻译到mono C#实现系列(4) 利用CountDownTimer类实现倒计时功能 mono版

    群里的朋友问利用CountDownTimer类实现倒计时功能怎么实现,我就百度了,参考http://blog.csdn.net/qq344429461/article/details/7521361写 ...

  7. CentOS 7进入救援模式的方法

    CentOS 7版本进入救援模式并修改密码:方法1: runlevel 显示当前的运行级别(进入救援模式需要进入单用户模式) 方法2: ①.开机时随便按下键盘,进入系统选择菜单 ②.选择第一项,按e键 ...

  8. spring boot快速入门 1 :创建项目、 三种启动项目方式

    准备工作: (转载)IDEA新建项目时,没有Spring Initializr选项 最近开始使用IDEA作为开发工具,然后也是打算开始学习使用spring boot. 看着博客来进行操作上手sprin ...

  9. hibernate关联关系的crud之级联

    cascade级联,只会影响CRUD的CUD,不会影响读取.不设置级联,从多的一方能读出一的一方,设了级联,从一的一方,默认也不能读出多的一方. 如果两个对象之间有关联,不管是一对多,多对一,单向还是 ...

  10. 创建自己的区块链游戏SLOT——以太坊代币(三)

    一个以太坊合约版本的轮盘游戏,向合约转账ETH,有几率获得3,5,10,100倍奖励 合约地址:0x53DA598E70a1505Ad95cBF17fc5DCA0d2c51174b 捐赠ETH地址:0 ...