The All-purpose Zero

来源:互联网 发布:电视盒桌面软件 编辑:程序博客网 时间:2024/06/05 01:01

The All-purpose Zero

这里写图片描述
.
.
题意:给出一个串,0可以变换成任何数(包括负数),问最长严格上升子序列为多长。
.
.
解法:用数组记录长度为i的结尾最小为多少,如果每次读入一个0,那么数组中每个数都更新为前一个数加一,长度为1的赋为负无穷。如果读入的不是0,那么二分搜索刚好比它小的值,看能不能更新下一位。注意因为读入0时如果每一位都搜会很慢,考虑用一个值来记录整个数组都减了多少,然后再在前面插入一个负无穷就好了。时间复杂度为(NlogN)
.
.

#include <stdio.h>#include <stdlib.h>#include <string.h>const int max = 1000000;int f[300000], n, l, r, t, x;int main() {    //freopen("j.in","r",stdin);    int tt;    scanf("%d", &tt);    for (int cases = 1; cases <= tt; cases++) {        memset(f, 0, sizeof(f));        scanf("%d", &n);        scanf("%d", &x);        l = 150000; r = 150000;        t = 0;        if (x == 0) f[l] = -max;        else f[l] = x;        for (int i = 2; i <= n; i++) {            scanf("%d", &x);            if (x == 0) {                l--;                t++;                f[l] = -max-t;            } else {                int ll = l, rr = r, tt = l;                while (ll <= rr) {                    int mid = (ll+rr)/2;                    if (f[mid]+t < x) {                        tt = mid;                        ll = mid+1;                    } else rr = mid-1;                }                if (tt == l) {                    if (f[tt]+t < x) {                        if (tt == r) {                            r++;                            f[r] = x-t;                        } else {                            if (f[tt+1]+t > x) f[tt+1] = x-t;                        }                    } else f[tt] = x-t;                } else {                    if (tt == r) {                            r++;                            f[r] = x-t;                    } else  {                        if (f[tt+1]+t > x) f[tt+1] = x-t;                    }                }            }        }        printf("Case #%d: %d\n", cases, r-l+1);    }}
0 0
原创粉丝点击