能从iii走到所有跑道 相当于 能从iii走到111和nnn.

边反向后就相当于 能从111和nnn走到iii.

为了方便叙述,把111~nnn叫做x坐标,111~(m+1)(m+1)(m+1)叫做y坐标.

然后我们将图上下翻转(yyy坐标)后,能从111走到iii的话一定经过i−1i-1i−1条向右的边,且这些边的yyy坐标不下降.

那么我们设fl[i]fl[i]fl[i]表示从111走到iii最小加边数量,那么有fl[i]=i−1−LISfl[i]=i-1-LISfl[i]=i−1−LIS这里的LISLISLIS是x坐标在111~(i−1)(i-1)(i−1)的边的yyy坐标形成的最长不下降子序列长度.

这个东西可以O(nlogn)O(nlogn)O(nlogn)预处理出来,同时我们反着处理一遍向左的边就能处理出从nnn走到iii的最小加边数量fr[i]fr[i]fr[i].

最终答案一定是一段连续的区间[i,j][i,j][i,j].因为如果两个满足答案的位置不相邻,体现在边的yyy坐标序列上就是两座山峰,中间的值也一定可以形成山峰.如下图



假设两座山峰为L,RL,RL,R.那么对于在[L,R][L,R][L,R]中的点,如果在M左边就取①上的点,如果在M右边就取②上的点,这样也一定能够形成总长为nnn的山峰.

所以说要求的就是区间[i,j][i,j][i,j]满足fr[i]+fl[j]&lt;=kfr[i]+fl[j]&lt;=kfr[i]+fl[j]<=k的最长区间长度.

由于fr[i]fr[i]fr[i]递减,fl[i]fl[i]fl[i]递增,那么枚举iii增加的时候,为了让区间长度尽量大,jjj也一定不会变小.那么就开个变量存一下当前jjj的位置然后往后面挪动就行了.O(n)O(n)O(n)

总时间复杂度O(nlogn)O(nlogn)O(nlogn).

注意这道题要减去原本就能够被1,n1,n1,n都到达的跑道的数量.

CODE

#include<bits/stdc++.h>
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; for(;!isdigit(ch=getc());)if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 100005;
int n, m, p, k, T[MAXN], fl[MAXN], fr[MAXN];
vector<pair<int,int> >el[MAXN], er[MAXN];
inline void chkmax(int &x, int y) { if(y > x) x = y; };
inline void upd(int x, int val) {
while(x <= m) chkmax(T[x], val), x += x&-x;
}
inline int qsum(int x) { int re = 0;
while(x) chkmax(re, T[x]), x -= x&-x;
return re;
}
int main() {
read(n), read(m), read(p), read(k); ++m;
for(int i = 1, x, y, z; i <= p; ++i) {
read(x), read(y), read(z); y = m-y;
if(z) el[x+1].push_back(make_pair(y, 0));
else er[x].push_back(make_pair(y, 0));
//这里的z=1和z=0两种边,将哪一种看作向左的边其实无所谓(图的左右翻转不影响答案)
//只要题目中给出的不同的两种边相对关系固定就行
}
int LIS = 0;
for(int i = 2; i <= n; ++i) { for(int j = 0, siz = el[i].size(); j < siz; ++j)
chkmax(LIS, el[i][j].second = qsum(el[i][j].first) + 1);
fl[i] = i - 1 - LIS;
for(int j = 0, siz = el[i].size(); j < siz; ++j)
upd(el[i][j].first, el[i][j].second);
}
for(int i = 1; i <= m; ++i) T[i] = 0;
LIS = 0;
for(int i = n-1; i >= 1; --i) {
for(int j = 0, siz = er[i].size(); j < siz; ++j)
chkmax(LIS, er[i][j].second = qsum(er[i][j].first) + 1);
fr[i] = n - i - LIS;
for(int j = 0, siz = er[i].size(); j < siz; ++j)
upd(er[i][j].first, er[i][j].second);
}
int j = 1, ans = 0, cnt = 0;
for(int i = 1; i <= n; ++i) {
while(j <= n && fr[i] + fl[j] <= k) ++j;
chkmax(ans, j - i);
if(!fl[i] && !fr[i]) ++cnt;
}
//printf("ans = %d\n", ans);
printf("%d\n", ans-cnt);
}

BZOJ 1107: [POI2007]驾驶考试egz / Luogu P3463 [POI2007]EGZ-Driving Exam (树状数组 LIS)的更多相关文章

  1. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

  2. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  3. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  4. luogu 2154 离散化+杨辉三角+树状数组

    将纵向固定,每次在横向找两个点,计算其中间墓地的贡献答案,离散化后同一行的预处理个数, 树状数组内存储C[up[i]][k] * C[down[i][k] 的值,每次更新时 down[横坐标]++; ...

  5. BZOJ 3594 [Scoi2014]方伯伯的玉米田(二维树状数组)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3594 [题目大意] 给出一个数列,选出k个区间使得区间内数全部加1, 求k次操作之后最 ...

  6. 【Luogu】P2154虔诚的墓主人(树状数组)

    题目链接 这题就是考虑我们有这样一个情况

  7. bzoj 3594: [Scoi2014]方伯伯的玉米田【二维树状数组+dp】

    设f[i][j]为前i棵玉米被拔高了j(因为是单调不降所以前面越高越好,所以每次拔一个前缀),转移是f[i][j]=f[k][l]+1,l<=j,a[k]+l<=a[i]+j,然后用二维树 ...

  8. bzoj 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛【dp+树状数组+hash】

    最长上升子序列.虽然数据可以直接n方但是另写了个nlogn的 转移:f[i]=max(f[j]+1)(a[j]<a[i]) O(n^2) #include<iostream> #in ...

  9. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

    吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...

随机推荐

  1. 石子合并(直线版+环形版)&(朴素写法+四边形优化+GarsiaWachs算法)

    石子合并-直线版 (点击此处查看题目) 朴素写法 最简单常见的写法就是通过枚举分割点,求出每个区间合并的最小花费,从而得到整个区间的最小花费,时间复杂度为O(n^3),核心代码如下: ; i < ...

  2. Hystrix服务容错保护

    一.什么是灾难性雪崩效应? 造成灾难性雪崩效应的原因,可以简单归结为下述三种: 服务提供者不可用.如:硬件故障.程序BUG.缓存击穿.并发请求量过大等. 重试加大流量.如:用户重试.代码重试逻辑等. ...

  3. phpexcel 生成大于26列数据

    function excelExport2($fileName = '', $headArr = [], $data = [], $widths=[]) { ob_clean(); // $fileN ...

  4. luogu P2423 [HEOI2012]朋友圈 (最大团)

    在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着. 一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目.两个国家看成是 ...

  5. weblogic连接池

    1.在 使用JDBC连接池的过程中,最常见的一个问题就是连接池泄漏问题.一个池里面的资源是有限的,应用用完之后应该还回到池中,否则池中的资源会被耗尽. WebLogic Server提供了一个Inac ...

  6. TreeSet——实现Comparable接口并重写CompareTo()方法

    TreeSet是以自然顺序存的数据,例如 Set<Student> students=new TreeSet(); students.add(new Student("111&q ...

  7. pthread 笔记

    1.创建线程 res = pthread_create(&a_thread, NULL, thread_function1, NULL); if (res != 0) { perror(&qu ...

  8. vue页面中图片不显示解决

    在做新版组态界面的时候,用vue框架实现,在配置页面图片的时候发现有一张图片明明页面输入的路径是对的可是图片就是不显示出来 现象: network页面资源也不报错,而且状态码竟然还是200,点prev ...

  9. SQL:MYSQL入门

    MYSQL(关系型数据库管理系统) 参考手册:http://www.w3school.com.cn/sql/index.asp 给大家讲一下数据库:常见的有 ACCESS.MSSSQL.MYSQL.O ...

  10. (转)Android刷机的一些知识整理

    刷机概述刷机原因刷机可以升级和破解固件(在Android上:即可以升级系统,更改系统,获取Root权限):破解系统的原因①安装第三方软件不需要签名,不受证书的束缚:②修改系统的文件,达到系统的瘦身,以 ...