统计长度为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 session学习笔记(实例代码)

    http  无状态协议 一个服务器向客户端发送消息的时候有三条信息 一是状态二是头信息三是内容 会话控制 让一个用户访问每个页面,服务器都知道是哪个用户访问 cookie cookie是通过头信息发送 ...

  2. delphi 自带报告内存泄漏

    //报告内存泄漏 ReportMemoryLeaksOnShutdown := true;

  3. MyEclipse的一些配置

    1.配置默认编码 配置整个MyEclipse的默认编码 window--->Preferences-->General-->WorkSpace--->TextFileEncod ...

  4. MQ 2035(MQRC_NOT_AUTHORIZED)

    当使用MQ7.1或7.5时,如果使用MQ管理员账号去连接MQ服务器,可能会报以下的错误,提示你权限不足. 2035 MQRC_NOT_AUTHORIZED 在之前的版本中是没有这个问题的. 原因是在7 ...

  5. mac使用wget下载网站(仿站)

    wget -c -r -np -k -L -p http://www.xxxx.com 参考 wget的安装 http://blog.csdn.net/ssihc0/article/details/7 ...

  6. BZOJ 1588 营业额统计 Splay

    主要操作为Splay中插入节点,查找前驱和后继节点. 1: #include <cstdio> 2: #include <iostream> 3: #include <c ...

  7. hbase-site.xml 参数设置

    <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="confi ...

  8. Jquery异步请求简单实例(转)

    本文引用自Xingsoft. 一.Jquery向aspx页面请求数据 前台页面JS代码:             $("#Button1").bind("click&qu ...

  9. python学习笔记11(函数二): 参数的传递、变量的作用域

    一.函数形参和实参的区别 形参全称是形式参数,在用def关键字定义函数时函数名后面括号里的变量称作为形式参数. 实参全称为实际参数,在调用函数时提供的值或者变量称作为实际参数. >>> ...

  10. ios 中定时器:NSTimer, CADisplayLink, GCD

    #import "ViewController.h" #import "RunloopViewController.h" @interface ViewCont ...