Hdu 3564 Another LIS 线段树+LIS
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1361 Accepted Submission(s): 492
Problem Description
There is a sequence firstly empty. We begin to add number from 1 to N to the sequence, and every time we just add a single number to the sequence at a specific position. Now, we want to know length of the LIS (Longest Increasing Subsequence) after every time's add.
Input
An integer T (T <= 10), indicating there are T test cases.
For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
Output
For the k-th test case, first output "Case #k:" in a separate line, then followed N lines indicating the answer. Output a blank line after every test case.
Sample Input
1
3
0 0 2
Sample Output
Case #1:
1
1
2
Hint
In the sample, we add three numbers to the sequence, and form three sequences.
a. 1
b. 2 1
c. 2 1 3
Author
standy
Source
思路:由于是从大到小插值的,那么我们只需要知道最终的序列,再对其求一遍LIS即可。可以用线段树求最终的序列,从后往前考虑,一开始有n个空位,对于每个数的插入位置a[i],其应该放在从左往右的第a[i]个空格,放完数后该空格被占用。该问题相当于给出n个数,多次操作,找出第k1个数后,将该数删去,继续找第k2个数。。。

#include <bits/stdc++.h> using namespace std; const int N = 100000 + 5; #define lson rt << 1, l, m #define rson rt <<1|1, m + 1, r int num[N << 2]; int a[N], pos[N], ans[N], res[N], n; void build(int rt, int l, int r) { num[rt] = r - l + 1; if(l == r) return ; int m = (l + r) >> 1; build(lson); build(rson); } void update(int rt, int l, int r, int k, int v) { if(l == r) { pos[l] = v; num[rt] = 0; return; } int m = (l + r) >> 1; if(k > num[rt << 1]) update(rson, k - num[rt << 1], v); else update(lson, k, v); num[rt] = num[rt << 1] + num[rt << 1|1]; } int LIS[N], len; void solve() { len = 1; LIS[0] = 0; for(int i = 1; i <= n; ++i) { int p = upper_bound(LIS, LIS + len, pos[i]) - LIS - 1; LIS[p + 1] = pos[i]; ans[i] = p + 1; if(p + 1 == len) len++; } } int main() { // freopen("in.txt", "r", stdin); int _, cas = 1; scanf("%d", &_); while(_ --) { scanf("%d", &n); build(1, 1, n); // puts("-----BUG-----"); for(int i = 1; i <= n; ++i) { scanf("%d", a + i); a[i]++; } for(int i = n; i >= 1; --i) update(1, 1, n, a[i], i); solve(); for(int i = 1; i <= n; ++i) res[ pos[i] ] = ans[i]; for(int i = 2; i <= n; ++i) res[i] = max(res[i], res[i - 1]); printf("Case #%d:\n", cas++); for(int i = 1; i <= n; ++i) printf("%d\n", res[i]); puts(""); } }
分类:
Hdu
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧