汕头市队赛 SRM14 T2 最长上升子序列

最长上升子序列

(tree.pas/c/cpp) 128MB 1s

有一个长度为n的序列a[i],其中1到n的整数各自在a[i]中出现恰好一次。

现在已知另一个等长的序列f[i],表示a[i]中以第i个位置结尾的最长上升子序列的长度,请还原出a[i]。

输入格式

第一行一个正整数n。

接下来一行n个数,其中第i个数表示f[i]。

输出格式

一行,n个整数,表示序列a[i],如果答案不唯一,任意输出一种。

样例输入

7

1 2 3 2 4 4 3

样例输出

1 4 5 2 7 6 3

样例解释

以每个a[i]结尾的最长上升子序列分别为{1},{1,4},{1,4,5},{1,2},{1,4,5,7},{1,4,5,6},{1,2,3}

数据范围与约定

对于30%的数据,n<=10

对于另外40%的数据,n<=1000

对于所有数据,n<=100000

——————————————————————————————————————————

这道题当然可以按 长度 以及 位置的前后进行一波排序解决问题(长度从小到大 位置后(大)的在前)

这样复杂度是nlogn

所以我写的是拓扑排序(O(n))

我们枚举到一个数 向值比他小1的数连线 表示他比他大 1

同时向和他一样大的在他前一位的连线 因为这样大小关系一样是确定的

然后就一波拓扑排序解决问题辣

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=2e4+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int n,m,l,ans;
int sum[M],w[M],f[507][M],mx;
int q[M],ql,qr,k;
int F(int x){return f[k-1][x]-sum[x];}
int main(){
    freopen("hard.in","r",stdin);
    freopen("hard.out","w",stdout);
    n=read(); m=read(); l=read();
    for(int i=l;i<n+l;++i) w[i]=read();
    n=n+2*l-1;
    for(int i=1;i<=n;++i) sum[i]=sum[i-1]+w[i];
    for(int i=0;i<l;++i) f[1][i]=-inf;
    for(int i=l;i<=n;++i) f[1][i]=sum[i]-sum[i-l];
    for(k=2;k<=m;++k){
        ql=1,qr=0;
        mx=-inf;
        for(int i=0;i<l;++i) f[k][i]=-inf;
        for(int i=l;i<=n;++i){
            while(ql<=qr&&q[ql]<=i-l) ++ql;
            while(ql<=qr&&F(q[qr])<=F(i-1)) --qr;
            q[++qr]=i-1;
            mx=max(mx,f[k-1][i-l]);
            f[k][i]=max(mx+sum[i]-sum[i-l],F(q[ql])+sum[i]);
        }
    }
    ans=0;
    for(int i=1;i<=m;++i)
        for(int j=l;j<=n;++j) ans=max(ans,f[i][j]);
    printf("%d\n",ans);
    return 0;
}

时间: 2024-10-09 20:52:42

汕头市队赛 SRM14 T2 最长上升子序列的相关文章

汕头市队赛 SRM1X T2 ——扫描线

绵津见-终 SRM 13 背景 "西瓜也是可以种在海上的!"--绵津见 然而种在海上的西瓜最需要防范的,是时不时会涌向瓜田的阵阵海浪. 幸好,身为海神的绵津见可以释放魔法"水平如镜"来阻止海浪拍打西瓜. 然而,当西瓜一个接一个成熟之时,它们就要离开瓜田,飘向遥远的彼岸.绵津见的魔法无法保护离开瓜田的西瓜们,但至少,也得知道西瓜们遭遇了多大的风浪啊. 描述 我们用一个坐标系来描述大海,绵津见的瓜田位于x轴下方,每当有一个西瓜成熟时,它会从x轴上一点出发,沿一条平行y轴

汕头市队赛 SRM13 T2

这道题很容易想到是二分 但是因为可能会爆LL 所以要加一波特判 #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const LL M=1e6+7,mx=1e18; LL read(){ LL ans=0,c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>

汕头市队赛SRM14 T3覆盖

我们可以考虑两种情况 区间之间不相重叠 和 重叠 f[i][j]表示以当前最后一个区间以 i 结尾 并且选了 j 个区间 不相重叠的话 只要选 1-i-w 的max再加上 包含i在内的前四个数的和 相交的话 考虑因为可选的区间长度是固定的 所以我们可以考虑单调队列优化 sum维护的是前缀和 f[i][j]=f[k][j-1]+sum[i]-sum[k] 这样因为sum[i]是固定的 所以我们队列里维护的是f[k][j-1]-sum[k]就好辣 #include<cstdio> #include

汕头市队赛 SRM16 T2

描述 猫和老鼠,看过吧?猫来了,老鼠要躲进洞里.在一条数轴上,一共有n个洞,位置分别在xi,能容纳vi只老鼠.一共有m只老鼠位置分别在Xi,要躲进洞里,问所有老鼠跑进洞里的距离总和最小是多少. 输入格式 两个用空格隔开的整数m和n. 这一行m个数字分别表示老鼠的位置 接下来n行每行两个数字分别表示洞的位置和容纳量 输出格式 一个整数,表示最小的距离总和.(如果无解,输出-1) 样例输入 4 5 6 2 8 9 3 6 2 1 3 6 4 7 4 7 样例输出 11----------------

汕头市队赛 SRM14 T1 计算几何瞎暴力

计算几何瞎暴力 (easy.pas/c/cpp) 128MB 1s 在平面上,给定起点和终点,有一面墙(看作线段)不能穿过,问从起点走到终点的最短路程. 输入格式 输入一行,包含8个用空格分隔的整数xS,yS,xT,yT,x1,y1,x2,y2,依次表示起点(xS,yS),终点(xT,yT),线段(x1,y1)-(x2,y2). 输出格式 输出一个整数,表示答案四舍五入到整数后的值,保证答案精确值的小数点后一位不是4或5. 样例输入 1 1 2 2 1 2 2 1 样例输出 2 样例解释 走折线

汕头市队赛 C KMP codeforces B. Image Preview

汕头市队赛题目传送门 codeforces题目传送门 这道题我的做法是 尝试先往左走然后往右走 或者先往右走然后往左走 然后注意一下枚举顺序就okay啦 #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e6+7; LL read(){ LL ans=0,f=1,c=getchar(); while(c

汕头市队赛 SRM 07 D 天才麻将少女kpm

这道题放了很久还是回来补了 D 天才麻将少女KPM SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     KPM上周叒打了n场麻将,但她这次又没控分,而且因为是全市参与的麻将大赛,所以她的名次范围是0..10^5.     名次可能等于0是因为KPM那场没去打= =     没去打就意味着无限的可能性.     KPM叒想要让自己的名次严格递增.为了避免被妹子怀疑,她只能把没打的比赛的名次改成T..R中的整数     当然,n场全部严格递增是很难做到的.你只需

汕头市队赛SRM15

T1--czl SRM 15 众所周知,czl家养了一只可♂爱的***(已屏蔽),那只东西很贪吃,所以czl家很多零食仓库,然而这些仓库里有很多老鼠. 为了心爱的***,czl决定点燃纯艾条,用烟熏老鼠. 共有N个仓库,编号1-N. 假设陵陵在第i个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散Ai 的距离,接着所有|i-j|<=Ai 的仓库 j 的老鼠被消灭. 陵陵是个爱护环境的人,他想知道最少需要多少支艾条,才可以消灭所有老鼠. [输入格式] 第一行:一个正整数,代表 N. 第二行:N 个非

汕头市队赛 SRM 07 A 你的麻将会排序吗

A 你的麻将会排序吗 SRM 07 曾经有过一些沉迷日麻的小孩纸,后来呀,他们都去寻找自己的世界了. kpm也是这样的小孩纸.他想有一只自动整理牌的机器.当麻将以给定的顺序进入机器时,通过机器的运转,使得麻将们出机器的顺序是递增的.所以kpm需要在机器中建立一些传送带 (假设这些传送带都是足够长,可以停放很多很多的麻将),问题是,现在kpm需要建立多少条传送带才能完成他的机器. kpm大概有10^5块麻将吧. 输入格式 第一行是一个不大于10^5的数,表述麻将的总数. 第二行是麻将依次进入机器的