统计长度为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的更多相关文章

  1. [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)

    树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...

  2. [POJ3378]Crazy Thairs

    Problem 给你一个数列,让你求由五个元素组成的顺序对的个数. Solution DP:用DP[i][j]表示把第j个作为五元组中第i个的方案数 则DP[i][j]=sum{DP[k][j-1]} ...

  3. poj分类 很好很有层次感。

    初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      ( ...

  4. 【转】POJ题目分类推荐 (很好很有层次感)

    OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一. ...

  5. 【转】ACM训练计划

    [转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...

  6. POJ 题目分类(转载)

    Log 2016-3-21 网上找的POJ分类,来源已经不清楚了.百度能百度到一大把.贴一份在博客上,鞭策自己刷题,不能偷懒!! 初期: 一.基本算法: (1)枚举. (poj1753,poj2965 ...

  7. (转)POJ题目分类

    初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推. ...

  8. acm常见算法及例题

    转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题  初期:一.基本算法:     (1)枚举. (poj17 ...

  9. poj分类

    初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      ( ...

随机推荐

  1. RFC822DateGMT

    function RFC822DateGMT(dd: TDateTime): string; const Days:..] of string= ('Sun','Mon','Tue','Wed','T ...

  2. Spark Streaming揭秘 Day15 No Receivers方式思考

    Spark Streaming揭秘 Day15 No Receivers方式思考 在前面也有比较多的篇幅介绍了Receiver在SparkStreaming中的应用,但是我们也会发现,传统的Recei ...

  3. Oracle分析函数 — sum, rollup, cube, grouping用法

    本文通过例子展示sum, rollup, cube, grouping的用法. //首先建score表 create table score( class  nvarchar2(20), course ...

  4. ORA-12838: cannot read/modify an object after modifying it in parallel

    insert /*+ append */ into my_all_objects  select * from my_all_objects; select * from my_all_objects ...

  5. phpstorm运行在浏览器中执行php文件报502错误

    原因是之前mac自带的php5.5版本被我升级到了5.6 通过phpinfo()查看到目前php5.6的安装目录 重新制定一些interpreter的路径 /usr/local/php5/bin 就可 ...

  6. 基于Python+协程+多进程的通用弱密码扫描器

    听说不想扯淡的程序猿,不是一只好猿.所以今天来扯扯淡,不贴代码,只讲设计思想. 0x00 起 - 初始设计 我们的目标是设计一枚通用的弱密码扫描器,基本功能是针对不同类型的弱密码,可方便的扩展,比如添 ...

  7. Elasticsearch从0.90到1.2的不兼容变化-系统和设置

      本文为官方文档的翻译加个人理解.作者翻译时,elasticsearch(下面简称es)的版本为1.2.1.   1.系统级别及设置方面 1.1 es启动时,默认是作为一个前台程序启动.如果你想让e ...

  8. REST Design Concerns

    Less Requests, More data; one of the core RESTful API design paradigms is the concept of less API re ...

  9. idea14使用maven创建web工程

    参考博客:http://geeksun.iteye.com/blog/2179658 http://www.bubuko.com/infodetail-387387.html ------------ ...

  10. MySQL查询本周、上周、本月、上个月份数据的sql代码(转)

    感谢:http://www.jb51.net/article/32277.htm ----------------------------------------------------------- ...