统计长度为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. php微信支付(仅pc端扫码支付模式二)详细步骤.----仅适合第一次做微信开发的程序员

    本人最近做了微信支付开发,是第一次接触.其中走了很多弯路,遇到的问题也很多.为了让和我一样的新人不再遇到类似的问题,我把我的开发步骤和问题写出来,以供参考. 开发时间是2016/8/10,所以微信支付 ...

  2. php获取数组中重复数据的两种方法

    分享下php获取数组中重复数据的两种方法. 1,利用php提供的函数,array_unique和array_diff_assoc来实现 <?php function FetchRepeatMem ...

  3. sql新感悟(where 1 = 1)

    花了好久把YII框架看完发现一本很不错的书:SQL案例解析(清华大学出版社),看到一些比较有用的东西,感觉应该把他记录下来,看了好多页发现书中一直有 where 1=1,这样的语句,查过发现“wher ...

  4. xml学习总结(三)

    复杂Schema 扩展包含简单内容的复杂类型 <?xml version="1.0" encoding="UTF-8"?> <xs:schem ...

  5. 帝国cms中 内容分页的SEO优化

    关于内容页如果存在分页的话,我们想区分第一页和后面数页,当前的通用做法是在标题上加入分页码,帝国cms中如何做到呢.我们可以修改在e/class/functions.php中的源码.找到找到GetHt ...

  6. K2 Blackpearl 4.6.8 安装步骤详解

    由于某些原因,我幼小的心灵受到了很大的创伤,倍感世态之炎凉,久久不能愈合,也因此很久没再接触K2 Blackpearl了.偶然来了兴趣,想整个K2的环境,闲暇之余了解其新功能,温故知新,也希望从中能讨 ...

  7. UML include、generalization、extend、association

    1.别人的说法 转自:http://www.cnblogs.com/shinings/archive/2009/04/21/1440765.html 共性:都是从现有的用例中抽取出公共的那部分信息,作 ...

  8. google calendar api v3

    google api for .net nuget Install-Package Google.Apis.Calendar.v3 oauth2 for asp.net http://www.code ...

  9. iOS 跳转到系统的设置界面-b

    在项目中,我们经常会碰到使用位置的需求.当用户设置app不允许使用位置的时候,最好的用户体验就是直接调转到系统的位置设置界面,进行设置. 本人已经测试,在5c iOS8.3系统 和 5s iOS7.1 ...

  10. man手册使用

    1.是普通的命令 2.是系统调用,如open,write之类的(通过这个,至少可以很方便的查到调用这个函数,需要加什么头文件) 3.是库函数,如printf,fread 4.是特殊文件,也就是/dev ...