统计长度为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. centos6.5 最小化安装无法上网

    在VMware里装了个centos 6.5.  最小化安装后无法上网.在 google里找到答案 第一步:执行命令启动网卡 (最小化安装不是自动启动的) [root@localhost]# ifcon ...

  2. Servlet一次乱码排查后的总结(转)

    原文地址:http://my.oschina.net/looly/blog/287255 由来 在写一个小小的表单提交功能的时候,出现了乱码,很奇怪request上来的参数全部是乱码,而从数据库查询出 ...

  3. 【IOS】分享下近一年IOS开发的经验总结

    从上个暑假末到现在,自己做IOS开发也快一年了.从一开始的什么都不知道,到现在大多事都能搭上一两手,期间经历了很多事情.下面来和大家分享一下心得和感触. 1.现在移动领域的知识更新的很快,无论是IOS ...

  4. 关于FileSystemWatcher监听文件创建

    FileSystemWatcher中的Created事件不但可以监听用户创建的文件,当用户删除某个文件时,系统会在再监听的那个盘上的回收站创建一个文件,在回收站创建的文件也会触发Created事件,而 ...

  5. Create a SharePoint Application Page for Anonymous Access

    http://dishasharepointworld.blogspot.com/2011/07/how-to-create-sharepoint-application_1072.html http ...

  6. 使用eclipse生成文档(javadoc)

    使用eclipse生成文档(javadoc)主要有三种方法:1,在项目列表中按右键,选择Export(导出),然后在Export(导出)对话框中选择java下的javadoc,提交到下一步.在Java ...

  7. 使用 PIVOT 和 UNPIVOT

    http://msdn.microsoft.com/zh-cn/library/ms177410%28v=SQL.90%29.aspx 可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式 ...

  8. centos7安装mplayer以及出现的各种问题

    首先,centos7默认的视频播放器基本不能用,这里我们选择mplayer作为视频播放器. 安装的过程,痛并快乐着....... 首先我们去mplayer的官网下载需要的文件,http://www.m ...

  9. easyui 使特定tab处于选中状态

    <div id="tabs" class="easyui-tabs"> <div title="Tab1" style=& ...

  10. [转载]jquery cookie的用法

    原文地址:http://www.cnblogs.com/qiantuwuliang/archive/2009/07/19/1526663.html jQuery cookie是个很好的cookie插件 ...