我出的一些题
才出题不久,题目挺简单的。
U509345 排序差
出题人来一发题解 (虽然好像很简单,但我就是要写!
首先可以发现一个很显然的事实,一个序列排序后除第一个数外每个数与前一个差值之和就是最后一个数减去第一个数,即 。因此我们直接把序列 中最小的数和最大的数放在第一个和第二位置,这样对于 , 都等于最大的数减去最小的数,答案就是 (maxa - mina)(n-1)
。
最长不降的Flappy Bird
出题人题解。
前置知识:离散化,简单dp,线段树。
容易发现,一定存在一个最长不降序列的结尾数是某个区间的 。因此我们考虑离散化所有的区间的 ,记 表示到当前位置以 结尾的最长不降子序列长度,那么当前区间 必然可以使所有 的 加一。同时 可能可以被比 小的 更新,所以对于所有小于 的 求一个最大的 , 取 即可。
区间修改、单点查询,很明显直接线段树优化。时间复杂度 。
ps:其实这也可以是原版最长不降子序列的线段树做法。
std:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define pb push_back
#define fi first
#define se second
#define looktime cerr << 1.0 * clock() / CLOCKS_PER_SEC << endl
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mp make_pair
#define pii pair<int, int>
#define uint unsigned int
//--------------------------------------------------------------------------------------------
#define N 100010
#define p1 (p * 2)
#define p2 (p * 2 + 1)
#define l(p) tree[p].l
#define r(p) tree[p].r
#define maxx(p) tree[p].maxx
#define tag(p) tree[p].tag
struct xds{
int l, r, maxx, tag;
}tree[N * 4];
int n, cnt;
pii a[N];
int tv[N * 2];
int find(int x){
return lower_bound(tv + 1, tv + cnt + 1, x) - tv;
}
void pushup(int p){
maxx(p) = max(maxx(p1), maxx(p2));
}
void pushdown(int p){
if(tag(p)){
tag(p1) += tag(p), tag(p2) += tag(p);
maxx(p1) += tag(p), maxx(p2) += tag(p);
tag(p) = 0;
}
}
void build(int p, int l, int r){
l(p) = l, r(p) = r;
if(l == r) {return ;}
int mid = l + r >> 1;
build(p1, l, mid);
build(p2, mid + 1, r);
}
int ask(int p, int l, int r){
if(l <= l(p) && r(p) <= r){
return maxx(p);
}
pushdown(p);
int mid = l(p) + r(p) >> 1, tmp = 0;
if(l <= mid) tmp = ask(p1, l, r);
if(r > mid) tmp = max(tmp, ask(p2, l, r));
return tmp;
}
void add(int p, int l, int r, int x){
if(l <= l(p) && r(p) <= r){
maxx(p) += x, tag(p) += x;
return ;
}
pushdown(p);
int mid = l(p) + r(p) >> 1;
if(l <= mid) add(p1, l, r, x);
if(r > mid) add(p2, l, r, x);
pushup(p);
}
void change(int p, int l, int x){
if(l(p) == r(p)){
maxx(p) = x;
return ;
}
pushdown(p);
int mid = l(p) + r(p) >> 1;
if(l <= mid) change(p1, l, x);
else change(p2, l, x);
pushup(p);
}
void init(){
sort(tv + 1, tv + cnt + 1);
cnt = unique(tv + 1, tv + cnt + 1) - (tv + 1);
build(1, 1, cnt);
}
signed main(){
// freopen("data.in", "r", stdin);
IOS;
cin >> n;
rep(i, 1, n){
int x;
cin >> x;
a[i] = {x, x};
tv[++cnt] = a[i].fi;
}
init();
rep(i, 1, n){
int l = find(a[i].fi), r = find(a[i].se);
add(1, l, r, 1);
if(l > 1 && ask(1, 1, l - 1) + 1 > ask(1, l, l)){
change(1, l, ask(1, 1, l - 1) + 1);
}
}
cout << ask(1, 1, cnt) << endl;
}
本文作者:星影流灿
本文链接:https://www.cnblogs.com/yduck/p/18574936
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步