我出的一些题

才出题不久,题目挺简单的。

U509345 排序差

出题人来一发题解 (虽然好像很简单,但我就是要写!

首先可以发现一个很显然的事实,一个序列排序后除第一个数外每个数与前一个差值之和就是最后一个数减去第一个数,即 f(i)=j=2iajaj1=aia1。因此我们直接把序列 an 中最小的数和最大的数放在第一个和第二位置,这样对于 i[2,n], f(i) 都等于最大的数减去最小的数,答案就是 (maxa - mina)(n-1)

最长不降的Flappy Bird

出题人题解。

前置知识:离散化,简单dp,线段树。

容易发现,一定存在一个最长不降序列的结尾数是某个区间的 li。因此我们考虑离散化所有的区间的 li,记 fj 表示到当前位置以 j 结尾的最长不降子序列长度,那么当前区间 [li,ri] 必然可以使所有 j[li,ri]fj 加一。同时 fli 可能可以被比 li 小的 j 更新,所以对于所有小于 lij 求一个最大的 fjflimax(fli,fj+1) 即可。

区间修改、单点查询,很明显直接线段树优化。时间复杂度 O(nlogn)

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 中国大陆许可协议进行许可。

posted @   星影流灿  阅读(11)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起