http://acm.hdu.edu.cn/showproblem.php?pid=3564

题意

给出1~n的插入顺序,要求每次插入之后的LIS

分析

首先用线段树还原出最终序列。因为插入的顺序是按1-n的顺序插入的,我们还原位置后,直接对位置进行求LIS,即为当前数的LIS。这里根据数据是从小到大插入的性质,用了比较巧妙的解法。先把每个数的位置保存起来,从小到大遍历,二分查找当前数据的位置处在已求出的LIS中的位置,比较长度后更新,再加入这个数据的位置,因为数据是从小到大的。

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d\n",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define lc idx<<1
#define rc idx<<1|1
#define lson l,mid,lc
#define rson mid+1,r,rc
using namespace std;
typedef long long ll;
template <class T>
void test(T a){cout<<a<<endl;}
template <class T,class T2>
void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
const int N = 1e6+;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = ;
int T;
void testcase(){
printf("Case #%d:\n",++T);
}
const int MAXN = 2e5+;
const int MAXM = ;
struct node{
int l,r,w;
}tree[MAXN<<];
int n,len;
int ans[MAXN],val[MAXN],pos[MAXN],dp[MAXN];
void build(int l,int r,int idx){
tree[idx].l=l,tree[idx].r=r;
// tree[idx].w=r-l+1;
if(l==r){
tree[idx].w=;
return;
}
int mid = (l+r)>>;
build(lson);
build(rson);
tree[idx].w=tree[lc].w+tree[rc].w;
}
void update(int pos,int val,int idx){
if(tree[idx].l==tree[idx].r){
tree[idx].w--;
ans[val]=tree[idx].l;
return;
}
if(pos<=tree[lc].w) update(pos,val,lc);
else update(pos-tree[lc].w,val,rc);
tree[idx].w=tree[lc].w+tree[rc].w;
}
int bin(int k){
int l=,r=len;
while(l<=r){
int mid = (l+r)>>;
if(k>dp[mid]) l=mid+;
else r=mid-;
}
return l;
}
int main() {
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int t;
scd(t);
T=;
while(t--){
scd(n);
for(int i=;i<=n;i++) scd(pos[i]),val[i]=i;
build(,n,);
for(int i=n;i>;i--) update(pos[i]+,val[i],);
testcase();
len=;
for(int i=;i<=n;i++){
int k =bin(ans[i]);
len=max(len,k);
dp[k]=ans[i];
printf("%d\n",len);
}
puts("");
}
return ;
}

HDU - 3564 Another LIS(LIS+线段树)的更多相关文章

  1. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  2. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  3. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  4. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  5. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  6. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

  7. hdu 1754 I Hate It 线段树 点改动

    // hdu 1754 I Hate It 线段树 点改动 // // 不多说,裸的点改动 // // 继续练 #include <algorithm> #include <bits ...

  8. hdu 1166 敌兵布阵 线段树 点更新

    // hdu 1166 敌兵布阵 线段树 点更新 // // 这道题裸的线段树的点更新,直接写就能够了 // // 一直以来想要进线段树的坑,结果一直没有跳进去,今天算是跳进去吧, // 尽管十分简单 ...

  9. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  10. HDOJ 题目3564 Another LIS(线段树单点更新,LIS)

    Another LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

随机推荐

  1. Maven-Build Lifecycle(构建生命周期)

    https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html https://www.w3cschoo ...

  2. activiti 工作流 动态 设置 指定 节点任务人、责任人、组 的实现方式

    首先给大家看一下我的流程图: 流程文件leaveBill.bpmn <?xml version="1.0" encoding="UTF-8"?>&l ...

  3. Windows 下面 winrar 压缩简单记录

    1. 最高压缩比率 原始文件大小: 2.06g(3000余个文件) 压缩后文件大小:475m 压缩耗时:  210s 压缩率:22% 2. 较高压缩比率 压缩后文件大小:700 m 压缩率:32% 3 ...

  4. vim鼠标模式打开与关闭

    开启鼠标模式 :set mouse=x, x取值如下, 例如:set mouse=a, 开启所有模式的mouse支持 n 普通模式    v 可视模式    i 插入模式    c 命令行模式    ...

  5. delphi 的 LockType 锁类型

    LockType     锁类型       常数                                         值                           说明     ...

  6. BZOJ2178 圆的面积并(simpson积分)

    板子题.可以转一下坐标防止被卡.精度和常数实在难以平衡. #include<iostream> #include<cstdio> #include<cmath> # ...

  7. John's trip POJ - 1041(这题数据有点水)

    题意: 其实还是一个欧拉回路,但要按字典序走路: 解析: 我真是蠢啊emm... map[i][j]表示由顶点i经街道j会到达的顶点编号 然后枚举j就好了 用栈储存.. 虽然我不是这样写的 #incl ...

  8. codeforces 1B Spreadsheets

    In the popular spreadsheets systems (for example, in Excel) the following numeration of columns is u ...

  9. 自学Aruba4.3-Aruba AC基础配置(2)

    点击返回:自学Aruba之路 自学Aruba4.3-Aruba AC基础配置(2) 网络配置: Vlan .IP address port IP route IP dhcp 1. 网络配置VLAN . ...

  10. 自学Python2.8-条件(if、if...else)

    自学Python之路 自学Python2.8-条件(if.if...else) 1.if 判断语句 if语句是用来进行判断的,其使用格式如下:  if 要判断的条件: 条件成立时,要做的事情 当“判断 ...