poj 3378 Crazy Thairs

原创 2016年05月31日 16:48:58

题意/Description

    These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ≤ N ≤ 50000) numbers, which  are no more than 109, Crazy Thair is a group of 5 numbers {i, j, k, l, m} satisfying:

    1. 1 ≤ i < j < k < l < m  N

    2. Ai < Aj < Ak < Al < Am

  For example, in the sequence {2, 1, 3, 4, 5, 7, 6},there are four Crazy Thair groups: {1, 3, 4, 5, 6}, {2, 3, 4, 5, 6}, {1, 3, 4, 5, 7} and {2, 3, 4, 5, 7}.

Could you help Sempr to count how many Crazy Thairs in the sequence?


读入/Input

  Input contains several test cases. Each test case begins with a line containing a number N, followed by a line containing N numbers.


输出/Output

  Output the amount of Crazy Thairs in each sequence.


题解/solution

  网上的解题报告有两个解法:

    1:Dp+线段树+离散化+高精度

    2:树状数组+Dp+离散化+高精度

  靠,好复杂,又没有P语言,C语言不会翻,I give up it。然后LZH经过了N天N夜,在 big head 的叽叽咕咕下,在 pig 的乱搞下,AC啦。于是我狠狠的敲了一波标。

  讲一下DP:

    F[I,j]表示用a[i]结尾的长度为j的序列数目。

    F[I,j]= sum(F[k,j-1]) (1<=k<I且a[i]>a[k])

  因为读入的数有10^9大,而数列长度只有50000,想到离散化。可离散后,位置发生改变,排个序,在二分来查找。

要找它前方的所有比它小的树的t-1之和,想到了单点更新区间查询,线段树和数状数组都可以维护。由于长度为5,用5个树。完成这些,会发现结果会爆int64,于是加个高精度。看完后,你肯定惊恐

代码/Code
type
  arr=record
    x,y:longint;
  end;

var
  dp:array [0..50001,1..5] of int64;
  m,len,n,k:longint;
  f:array [0..50001] of longint;
  tree:array [0..50001] of arr;
  sum:array [0..101] of longint;

procedure qsort(l,r:longint);
var
  i,j,key,key1:longint;
  temp:arr;
begin
  if l>=r then exit;
  i:=l; j:=r;
  key:=tree[(l+r) shr 1].x;
  key1:=tree[(l+r) shr 1].y;
  repeat
    while (tree[i].x<key) or (tree[i].x=key) and (tree[i].y<key1) do inc(i);
    while (tree[j].x>key) or (tree[j].x=key) and (tree[j].y>key1) do dec(j);
    if i<=j then
      begin
        temp:=tree[i]; tree[i]:=tree[j]; tree[j]:=temp;
        inc(i);dec(j);
      end;
  until i>j;
  qsort(l,j);
  qsort(i,r);
end;

function bit(n:longint):longint;
begin
    exit(n and -n);
end;

procedure jf(n:qword);
var
  i:longint;
  a,b:array [0..100] of longint;
begin
  fillchar(a,sizeof(a),0);
  fillchar(b,sizeof(b),0);
  i:=-1;
  while n>0 do
    begin
      inc(i);
      a[i]:=n mod 10;
      n:=n div 10;
    end;
  i:=-1;
  while i<100 do
    begin
      inc(i);
      b[i]:=a[i]+sum[i]+b[i];
      if b[i]>=10 then
        begin
          inc(b[i+1]);
          b[i]:=b[i] mod 10;
        end;
    end;
  for i:=0 to 99 do
    sum[i]:=b[i];
end;

function count(n,j:longint):int64;
var
  ans:int64;
begin
  ans:=0;
  while n>0 do
    begin
      ans:=ans+dp[n,j];
      n:=n-bit(n);
    end;
  exit(ans);
end;

procedure update(n,j:longint;k:int64);
begin
  while n<=m do
    begin
      dp[n,j]:=dp[n,j]+k;
      n:=n+bit(n);
    end;
end;

procedure dpp(n:longint);
var
  tem:int64;
  i,j:longint;
begin
  fillchar(dp,sizeof(dp),0);
  fillchar(sum,sizeof(sum),0);
  len:=1;
  for i:=1 to n do
    begin
      tem:=count(f[i]-1,4);
      jf(tem);
      for j:=5 downto 2 do
        begin
          tem:=count(f[i]-1,j-1);
          update(f[i],j,tem);
        end;
      update(f[i],1,1);
    end;
  len:=100;
  while(sum[len]=0) and (len>0) do dec(len);
  for i:=len downto 0 do
    write(sum[i]);
  writeln;
end;

procedure main;
var
  i:longint;
begin
  while not eof do
    begin
      readln(n);
      m:=n;
      for i:=1 to n-1 do
        begin
          read(tree[i].x);
          tree[i].y:=i;
        end;
      readln(tree[n].x);
      tree[n].y:=n;
      qsort(1,n);
      f[tree[1].y]:=1; k:=0;
      for i:=1 to n do
        begin
          if tree[i].x=tree[i-1].x then f[tree[i].y]:=f[tree[i-1].y] else
            begin
              f[tree[i].y]:=k+1;
              inc(k);
            end;
        end;
      dpp(n);
    end;
end;

begin
  main;
end.


版权声明:转载?请说声“我不转载”,然后照做,谢谢。

poj 3378 Crazy Thairs 动态规划

题目链接:http://poj.org/problem?id=3378   题目大意:       找出原序列中满足: 1. 1 ≤ i  2. Ai j k l m       两个条件...
  • SG_SIQing
  • SG_SIQing
  • 2013年10月13日 20:47
  • 443

poj 3378 Crazy Thairs dp

用树状数组优化转移复杂度,结果会超long long,要用高精度。#include #include #include #include typedef unsigned long long ...
  • yrleep
  • yrleep
  • 2013年05月04日 02:18
  • 877

[PKU 3378]Crazy Thairs(平衡树)

【题目大意】:N个数(N),求5个互相不逆序的数的组合有多少个。【题目分析】:这个题的重要的地方在于要统计的是长度为5的正序序列的个数,我们就可以通过正序对个数的求法来类比出来正确的方法。正序的求法我...
  • Skyprophet
  • Skyprophet
  • 2009年09月08日 12:32
  • 642

POJ 3378 / UESTC 1460 - Crazy Thairs

UESTC 地址 :   http://acm.uestc.edu.cn/problem.php?pid=1460 POJ 地址 : http://poj.org/problem?id=3378...
  • diannaok
  • diannaok
  • 2012年07月28日 13:10
  • 555

poj 3378 Crazy Thairs 树状数组+高精度+dp

题意: 给一个长为n的序列,求里面长度为5的上升子序列有多少个。 分析: 树状数组c[i][j]表示以i结尾长度为j的序列数量,要用高精度。 代码: //poj 3378 //sep9 #i...
  • sepNINE
  • sepNINE
  • 2014年12月27日 23:08
  • 547

POJ 3378 - Crazy Thairs 树状数组+dp+离散化+高精度..

题意:                        给了一个数列,长度为N(1                题解:                        首先想到的是dp...dp[t][...
  • kk303
  • kk303
  • 2013年10月04日 17:33
  • 1168

【转】POJ 3378 Crazy Thairs(数据集中+DP+树状数组+高精度)

转自:http://blog.csdn.net/u013480600/article/details/21407795 POJ 3378 Crazy Thairs(数据集中+DP+树状数组+高精...
  • sdau20163942
  • sdau20163942
  • 2017年08月24日 11:47
  • 91

POJ 3378 Crazy Thairs(数据集中+DP+树状数组+高精度)

POJ3378 Crazy Thairs(数据集中+DP+树状数组+高精度) 分析:由于数据值大量不大,所以读入所有的数并对数值从新映射到[1,5000]. 令d[x][i]=y表示在序列中以值x结尾...
  • u013480600
  • u013480600
  • 2014年03月17日 21:03
  • 1090

POJ1637 Sightseeing tour(混合欧拉图的判断)

给出一张混合图(有有向边,也有无向边),判断是否存在欧拉回路。 首先是对图中的无向边随意定一个方向,然后统计每个点的入度(indeg)和出度(outdeg),如果(indeg - outdeg)是奇...
  • l04205613
  • l04205613
  • 2011年08月12日 11:51
  • 1660

Binary Index Tree And Segment Tree for PKU #3378 Crazy Thairs

Crazy ThairsTime Limit: 3000MSMemory Limit: 65536KTotal Submissions: 3111Accepted: 699DescriptionThe...
  • hhygcy
  • hhygcy
  • 2009年01月18日 23:55
  • 1450
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 3378 Crazy Thairs
举报原因:
原因补充:

(最多只允许输入30个字)