poj3378
统计长度为5的上升序列个数,
容易想到O(n^2)的dp
f[k,i]:=Σf[k-1,j] (1<=j<i,a[i]>a[j])
ans:=Σf[5,i]
但是显然会超时,需要考虑优化
怎样快速找到所有比当前高度小的状态的和呢?
答案很显然:树状数组
考虑到这题每个数<=10^9,我们要将其离散化,再映射到树状数组上
注意这题的最终答案爆int64,所以要用到高精度
var f,tr:array[..,..] of int64; //tr[i,j]表示树状数组,序列长度为i时,末尾离散化后高度为j;树状数组不会爆int64
ans,d:array[..] of integer;
a,b,c:array[..] of longint;
len,k,n,i,j:longint; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; procedure add(z:int64); //高精度加法
var i,la,w,x:longint;
begin
fillchar(d,sizeof(d),);
la:=;
while z<> do
begin
la:=la+;
d[la]:=z mod ;
z:=z div ;
end;
if la>len then len:=la;
inc(len);
w:=;
for i:= to len do
begin
x:=w+d[i]+ans[i];
ans[i]:=x mod ;
w:=x div ;
end;
if ans[len]= then dec(len);
end; function sum(p,q:longint):int64;
begin
sum:=;
while p> do
begin
sum:=sum+tr[q,p];
p:=p-lowbit(p);
end;
end; procedure work(p,q,z:int64); //将当前状态加入树状数组
begin
while p<=n do
begin
tr[q,p]:=tr[q,p]+z;
p:=p+lowbit(p);
end;
end; begin
while not eof do
begin
readln(n);
fillchar(c,sizeof(c),);
fillchar(tr,sizeof(tr),);
fillchar(f,sizeof(f),);
for i:= to n do
begin
read(a[i]);
b[i]:=i;
end;
readln;
sort(,n);
c[b[]]:=;
k:=;
for i:= to n do //离散化,注意重复的标相同的号
if a[i]=a[i-] then
c[b[i]]:=c[b[i-]]
else begin
inc(k);
c[b[i]]:=k;
end;
fillchar(ans,sizeof(ans),);
len:=;
for i:= to n do
begin
f[,i]:=;
work(c[i],,);
for j:= to do
begin
f[j,i]:=sum(c[i]-,j-); //dp
if f[j,i]> then work(c[i],j,f[j,i]);
end;
if f[,i]> then add(f[,i]);
end;
for i:=len downto do
write(ans[i]);
writeln;
end;
end.
总复杂度为O(nlogn)
质量很高的一道题
var f,tr:array[0..5,0..50010] of int64; //tr[i,j]表示树状数组,序列长度为i时,末尾离散化后高度为j;树状数组不会爆int64
ans,d:array[0..100] of integer;
a,b,c:array[0..50010] of longint;
len,k,n,i,j:longint;
function lowbit(x:longint):longint;
begin
exit(x and (-x));
end;
procedure add(z:int64); //高精度加法
var i,la,w,x:longint;
begin
fillchar(d,sizeof(d),0);
la:=0;
while z<>0 do
begin
la:=la+1;
d[la]:=z mod 10;
z:=z div 10;
end;
if la>len then len:=la;
inc(len);
w:=0;
for i:=1 to len do
begin
x:=w+d[i]+ans[i];
ans[i]:=x mod 10;
w:=x div 10;
end;
if ans[len]=0 then dec(len);
end;
function sum(p,q:longint):int64;
begin
sum:=0;
while p>0 do
begin
sum:=sum+tr[q,p];
p:=p-lowbit(p);
end;
end;
procedure work(p,q,z:int64); //将当前状态加入树状数组
begin
while p<=n do
begin
tr[q,p]:=tr[q,p]+z;
p:=p+lowbit(p);
end;
end;
begin
while not eof do
begin
readln(n);
fillchar(c,sizeof(c),0);
fillchar(tr,sizeof(tr),0);
fillchar(f,sizeof(f),0);
for i:=1 to n do
begin
read(a[i]);
b[i]:=i;
end;
readln;
sort(1,n);
c[b[1]]:=1;
k:=1;
for i:=2 to n do //离散化,注意重复的标相同的号
if a[i]=a[i-1] then
c[b[i]]:=c[b[i-1]]
else begin
inc(k);
c[b[i]]:=k;
end;
fillchar(ans,sizeof(ans),0);
len:=1;
for i:=1 to n do
begin
f[1,i]:=1;
work(c[i],1,1);
for j:=2 to 5 do
begin
f[j,i]:=sum(c[i]-1,j-1); //dp
if f[j,i]>0 then work(c[i],j,f[j,i]);
end;
if f[5,i]>0 then add(f[5,i]);
end;
for i:=len downto 1 do
write(ans[i]);
writeln;
end;
end.
poj3378的更多相关文章
- [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)
树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...
- [POJ3378]Crazy Thairs
Problem 给你一个数列,让你求由五个元素组成的顺序对的个数. Solution DP:用DP[i][j]表示把第j个作为五元组中第i个的方案数 则DP[i][j]=sum{DP[k][j-1]} ...
- poj分类 很好很有层次感。
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
- 【转】POJ题目分类推荐 (很好很有层次感)
OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一. ...
- 【转】ACM训练计划
[转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...
- POJ 题目分类(转载)
Log 2016-3-21 网上找的POJ分类,来源已经不清楚了.百度能百度到一大把.贴一份在博客上,鞭策自己刷题,不能偷懒!! 初期: 一.基本算法: (1)枚举. (poj1753,poj2965 ...
- (转)POJ题目分类
初期:一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. ...
- acm常见算法及例题
转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法: (1)枚举. (poj17 ...
- poj分类
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
随机推荐
- ComboBox Control Messages 消息
连接到MSDN,有时间完善这个.具体说明可点击进入msdn CB_ADDSTRING 添加一个字符串组合框的列表框.如果组合框没有cbs_sort风格,字符串添加到列表的结尾.否则,该字符串插入列表, ...
- cwm-recovery自动生成工具
android发展迅速,刷机已经成了一种习惯,cwm-recovery是必不可少的工具,下面我把自己用的自动生成cwm-recovery的工具发布出来,供友友们交流和学习,欢迎拍砖 已经公开发布在gi ...
- 【 socke】C# socket端口复用-多主机头绑定
什么是端口复用: 因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分.这种多重绑定便称之为端口复用 ...
- 进程(Process)和线程(Thread)的关系和区别
Definition定义-------------Process进程是应用程序的一次运行活动:从操作系统核 心角度来说,进程是操作系统分配和调度系统内存资源.cpu时间片等资源的基本单位,为正在运行的 ...
- ajaxfileupload踩过的坑
首先ajaxfileupload-jQuery.handleError is not a function这个错误,百度之后发现解决办法就是把 handleError: function( s, xh ...
- PAT-乙级-1002. 写出这个数 (20)
1002. 写出这个数 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 读入一个自然数n,计算其各位数字 ...
- httpsclient 自动获取证书 无证书访问 验证过能直接用
首先实现写一个 实现接口SecureProtocolSocketFactory的类. /** *ClassName: bcde *date: 2015年2月26日 下午4:51:01 * *@auth ...
- html10个特效(转载)
http://www.html5tricks.com/10-html5-jquery-image-animatin.html 现在网页上的图片已经不再是10几年前那种低像素的静态图片了,有了HTML5 ...
- ASP.NET 4.5.256 has not been registered on the Web server
请见:http://answers.microsoft.com/en-us/insider/forum/insider_apps-insider_other/aspnet-45256-has-not- ...
- 缺少编译器要求的成员“System.Runtime.CompilerServices.ExtensionAttribute..ctor” 解决方案
静态类中添加如下.此方法本人测试有效. //缺少编译器要求的成员“ystem.Runtime.CompilerServices.ExtensionAttribute..ctor” namespace ...