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)递归和分治法. ( ...
随机推荐
- php简单计数器程序(文本计数器、图形计数器)
分享二个php计数器的例子. 1).文本计数器 <?php $countfile="/count.txt"; //设置保存数据的文件 if (!file_exists($c ...
- slider jq小插件
html代码 <div class="r_list r_1" style="display:block;"> <div class=" ...
- 我的第一个canvas的作品:漫画对白编辑器
背景:一直都对canvas挺有有兴趣的,之前刚刚看了<HTML5 CANVAS基础教程>,写了篇读书笔记. 起因:老婆发来一张最近比较热的漫画图(友谊的小船说翻就翻什么的).这种漫画,经常 ...
- 给虚拟机中的CentOS7配置固定ip
在虚拟机中安装完了CentOS7之后,使用了DHCP来获取ip,vmware的网络连接使用了NAT模式.但是在把Linux设置为固定ip地址后,虚拟机里的linux可以ping通全网段的ip地址,但是 ...
- Teradata基础教程中的数据库试验环境脚本
Teradata基础教程中的数据库表: Customer: 客户信息表 Location: 位置信息表 Employee: 雇员信息表 Job: 工作信息表 Department: 部门表 ...
- 【网络】 NAT
NAT(Network Address Translation,网络地址转换)是1994年提出的.当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因 ...
- BZOJ 1588 营业额统计 Splay
主要操作为Splay中插入节点,查找前驱和后继节点. 1: #include <cstdio> 2: #include <iostream> 3: #include <c ...
- 类似nike+、香蕉打卡的转场动画效果-b
首先,支持并感谢@wazrx 的 http://www.jianshu.com/p/45434f73019e和@onevcat 的https://onevcat.com/2013/10/vc-tran ...
- CQRS学习——Cqrs补丁,async实验以及实现[其二]
实验——async什么时候提高吞吐 async是一个语法糖,用来简化异步编程,主要是让异步编程在书写上接近于同步编程.总的来收,在await的时候,相当于附加上了一个.ContinueWith(). ...
- [转载]Sublime Text 2 - 性感无比的代码编辑器!程序员必备神器!跨平台支持Win/Mac/Linux
代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大.灵活的编辑器,相信你和我一样,都不会例外. 我用过 ...