poj 3378 Crazy Thairs

来源:互联网 发布:地勘报告包括哪些数据 编辑:程序博客网 时间:2024/06/11 13:22
题目大意
  给一个长度为n的序列ai,定义五元组(i,j,k,l,m)满足:
  1<=i<j<k<l<m<=n;
  ai<aj<ak<al<am;
  问序列中有多少个满足条件的五元组。
  数据范围:1 <= n <= 50000, 0 <= ai <= 109

分析
  算法分析
ª 首先可以想到一个简单的dp方程
  设f[i][j]表示从前i个数中选择j个数且第j个数为a[i]的种数,则
  f[i][j] = f[i’][j - 1],  0 < i’ < i 且 a[i’] < a[i]
  直接作的时间复杂度是O(5 * n ^ 2)
ª 转移的时候其实是转移sum(f[i’][j-1]), 0 < i’ < i, 且a[i’] < a[i],具有区间性。
ª 利用树状数组优化转移时间复杂度
  最后一次要用高精度!!!
  可能会有重复的数。

代码
type  arr=array[0..100] of int64;var  n,m:longint;  b:array[0..109000,0..5] of int64;  a1,b1,c2:arr;  a,c,c1:array[0..100000] of int64;  i,j:longint;  k:int64;  s:char;procedure qsort(l,r:longint);var  i,j,key,temp:longint;begin  if l>=r then exit;  i:=l;j:=r;  key:=a[l+random(r-l+1)];  repeat    while (a[i]<key) do inc(i);    while (a[j]>key) do dec(j);    if i<=j then      begin        temp:=a[i];a[i]:=a[j];a[j]:=temp;        temp:=c[i];c[i]:=c[j];c[j]:=temp;        inc(i);dec(j);      end;  until i>j;  qsort(l,j);  qsort(i,r);end;function ji(a,b:arr):arr;var  i,j,k:longint;  jia:arr;begin  fillchar(jia,sizeof(jia),0);  if a[0]>b[0] then jia[0]:=a[0]               else jia[0]:=b[0];  for i:=1 to jia[0] do    begin      jia[i]:=jia[i]+a[i]+b[i];      jia[i+1]:=jia[i] div 10;      jia[i]:=jia[i] mod 10;    end;  if jia[jia[0]+1]>0    then inc(jia[0]);  ji:=jia;end;procedure add(x:qword);var  i,j,k:longint;begin  i:=1;  fillchar(c2,sizeof(c2),0);  c2:=a1;  fillchar(a1,sizeof(a1),0);  fillchar(b1,sizeof(b1),0);  while x<>0 do    begin      b1[i]:=x mod 10;      x:=x div 10;      i:=i+1;    end;  b1[0]:=i-1;  if b1[0]=0 then b1[0]:=1;  a1:=ji(b1,c2);end;procedure bian1(p:int64;c:int64;j:longint);begin  while p<=n do    begin      b[p,j]:=b[p,j]+c;      p:=p+(p and (p xor (p-1)));    end;end;function tong1(p:int64;j:longint):int64;begin  tong1:=0;  while p>0 do    begin      tong1:=tong1+b[p,j];      p:=p-(p and (p xor (p-1)));    end;end;begin  while not eof do  begin  readln(n);  fillchar(a,sizeof(a),0);  fillchar(c,sizeof(c),0);  fillchar(c1,sizeof(c1),0);  fillchar(a1,sizeof(a1),0);  fillchar(b,sizeof(b),0);  for i:=1 to n do    begin      read(a[i]);      c[i]:=i;    end;  readln;  qsort(1,n);  j:=0;  c1[c[1]]:=1;  for i:=1 to n do    begin      if a[i]=a[i-1]        then          c1[c[i]]:=c1[c[i-1]]        else          begin            c1[c[i]]:=j+1;            j:=j+1;          end;    end;  for i:=1 to n do    begin      add(tong1(c1[i]-1,4));      for j:=5 downto 2 do        begin          k:=tong1(c1[i]-1,j-1);          bian1(c1[i],k,j);        end;      bian1(c1[i],1,1);    end;  for i:=a1[0] downto 1 do    write(a1[i]);  writeln;  end;end.


1 0
原创粉丝点击