博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Codeforces261D]Maxim and Increasing Subsequence——树状数组+DP
阅读量:6005 次
发布时间:2019-06-20

本文共 1309 字,大约阅读时间需要 4 分钟。

题目链接:

题目大意:$k$次询问,每次给出一个长度为$n$的序列$b$及$b$中的最大值$maxb$,构造出序列$a$为$t$个序列$b$连接而成,求$a$的最长上升子序列。$n,maxb\le10^5,maxb*n\le2*10^7,t\le10^9$。

设$b$中不同数的个数为$sum$。如果$sum\le t$,那么答案就是$sum$(只需要从第$i$个序列$b$中取第$i$小的数即可)。现在只需要考虑$t<sum$的情况,因为$sum\le maxb$,所以$t<maxb$,这也就说明$n*t<n*maxb=2*10^7$,那么序列长度最大为$2*10^7$,我们只需要$O(nlog_{n})$求序列的最长上升子序列即可。直接$DP$,$f[i]$表示前$i$个数的最长上升子序列长度,用树状数组存前缀最大值然后扫一遍整个序列$DP$即可。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;int sum;int n,t,k;int b[100010];int a[20000010];int v[100010];int ans;int maxb;int f[20000010];map
mp;void add(int x,int k){ for(int i=x;i<=maxb;i+=i&-i) { v[i]=max(v[i],k); }}int ask(int x){ int res=0; for(int i=x;i;i-=i&-i) { res=max(res,v[i]); } return res;}int main(){ scanf("%d%d%d%d",&k,&n,&maxb,&t); while(k--) { memset(v,0,sizeof(v)); mp.clear(); sum=0; ans=0; for(int i=1;i<=n;i++) { scanf("%d",&b[i]); if(!mp[b[i]]) { sum++; mp[b[i]]=1; } } if(t>=sum) { printf("%d\n",sum); continue; } for(int i=1;i<=n*t;i++) { a[i]=b[(i-1)%n+1]; } for(int i=1;i<=n*t;i++) { f[i]=ask(a[i]-1)+1; ans=max(ans,f[i]); add(a[i],f[i]); } printf("%d\n",ans); }}

转载于:https://www.cnblogs.com/Khada-Jhin/p/10441696.html

你可能感兴趣的文章
MFC SendMessage和PostMessage 区别
查看>>
Linux : C语言pause()函数:让进程暂停直到信号出现
查看>>
atom插件安装
查看>>
洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分
查看>>
Unsupported configuration plain style unsupported in a navigation item
查看>>
4.  General Partitioning Guidelines
查看>>
五 Python基础 数据类型和变量
查看>>
字符编码的奥秘
查看>>
底部特征到底是什么样?
查看>>
oracles数据库定时任务
查看>>
WEBPACK & BABEL 打包项目
查看>>
各种乱码
查看>>
ASP.NET Core之跨平台的实时性能监控(2.健康检查)
查看>>
Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)...
查看>>
WP 7 开发:墓碑机制(多任务)
查看>>
在Win8上安装pyinstaller打包python成为可执行文件
查看>>
Java单线程文件下载,支持断点续传功能
查看>>
bzoj1503 郁闷的出纳员 splay版
查看>>
12.并发编程--Queue
查看>>
js弹出QQ对话框在线交谈
查看>>