• bzoj2006


    论将区间和转化为前缀和的重要性
    这题一旦转化为前缀和就非常明了了
    一段区间[l,r]的美妙程度就等于s[r]-s[l-1]
    对于这种无法计算出所有方案而取前k大的题目,我们一般分类别然后利用类别内的单调性用堆维护
    对于以i开头的区间,显然最美的长度在[l,r]之间的区间和
    显然是max(s[i+l-1~i+r-1]),设这个最美的为k
    次美的就是max(max(s[i+l-1~k-1]),max(s[k+1~i+r-1]),以此类推
    不难想到用ST预处理区间前缀最大值
    然后用大根堆维护开头为i,末端点位置在[p,q]上的最大值,
    每次取出当前堆最大值,设在k取到最大值,就将这个区间裂位[p,k-1],[k+1,q]两个区间加入堆
    一共进行k次,总的复杂度大约是O(klogn+nlogn)
    讲的可能不是很清楚,具体见程序吧

      1 type node=record
      2        tl,tr,st,loc:longint;
      3        num:int64;
      4      end;
      5 
      6 var heap:array[0..1000010] of node;
      7     d:array[0..30] of longint;
      8     f:array[0..500010,0..30] of longint;
      9     s:array[0..500010] of longint;
     10     n,k,l,r,i,j,x,y,t,p:longint;
     11     ans:int64;
     12 
     13 function max(a,b:longint):longint;
     14   begin
     15     if s[a]>s[b] then exit(a) else exit(b);
     16   end;
     17 
     18 function min(a,b:longint):longint;
     19   begin
     20     if a>b then exit(b) else exit(a);
     21   end;
     22 
     23 function ask(x,y:longint):longint;
     24   var k:longint;
     25   begin
     26     k:=trunc(ln(y-x+1)/ln(2));
     27     exit(max(f[x,k],f[y-d[k]+1,k]));
     28   end;
     29 
     30 procedure insert(i,x,y:longint);
     31   begin
     32     heap[t].tl:=x;
     33     heap[t].tr:=y;
     34     heap[t].st:=i;
     35     heap[t].loc:=ask(x,y);
     36     heap[t].num:=s[heap[t].loc]-s[i-1];
     37   end;
     38 
     39 procedure swap(var a,b:node);
     40   var c:node;
     41   begin
     42     c:=a;
     43     a:=b;
     44     b:=c;
     45   end;
     46 
     47 procedure up(i:longint);
     48   var j:longint;
     49   begin
     50     j:=i shr 1;
     51     while j>0 do
     52     begin
     53       if heap[i].num>heap[j].num then
     54       begin
     55         swap(heap[i],heap[j]);
     56         i:=j;
     57         j:=i shr 1;
     58       end
     59       else break;
     60     end;
     61   end;
     62 
     63 procedure sift(i:longint);
     64   var j:longint;
     65   begin
     66     j:=i shl 1;
     67     while j<=t do
     68     begin
     69       if (j<t) and (heap[j].num<heap[j+1].num) then inc(j);
     70       if heap[i].num<heap[j].num then
     71       begin
     72         swap(heap[i],heap[j]);
     73         i:=j;
     74         j:=i shl 1;
     75       end
     76       else break;
     77     end;
     78   end;
     79 
     80 begin
     81   readln(n,k,l,r);
     82   for i:=1 to n do
     83   begin
     84     readln(x);
     85     s[i]:=s[i-1]+x;
     86     f[i,0]:=i;
     87   end;
     88   t:=trunc(ln(n)/ln(2));
     89   d[0]:=1;
     90   for i:=1 to t do
     91     d[i]:=d[i-1]*2;
     92   for j:=1 to t do
     93     for i:=1 to n do
     94       if i+d[j]-1<=n then
     95         f[i,j]:=max(f[i,j-1],f[i+d[j-1],j-1])
     96       else break;
     97   t:=0;
     98   for i:=1 to n-l+1 do
     99   begin
    100     inc(t);
    101     insert(i,i+l-1,min(i+r-1,n));
    102     up(i);
    103   end;
    104   for i:=1 to k do
    105   begin
    106     p:=heap[1].loc;
    107     x:=heap[1].tl;
    108     y:=heap[1].tr;
    109     j:=heap[1].st;
    110     ans:=ans+int64(heap[1].num);
    111     swap(heap[1],heap[t]);
    112     dec(t);
    113     sift(1);
    114     if p>x then
    115     begin
    116       inc(t);
    117       insert(j,x,p-1);
    118       up(t);
    119     end;
    120     if p<y then
    121     begin
    122       inc(t);
    123       insert(j,p+1,y);
    124       up(t);
    125     end;
    126   end;
    127   writeln(ans);
    128 end.
    129 
    130  
    View Code
  • 相关阅读:
    java实现两个大数的相加
    转载:perl cpan 安装出现问题
    Linux下Clock skew detected的解决办法
    Object Builder Application Block
    Asp.Net MVC
    命名参数(转)
    (转)HTTP POST GET 本质区别详解
    jquery
    Introducing “Razor” – a new view engine for ASP.NET
    (转)全面讲解Oracle查询用户表空间
  • 原文地址:https://www.cnblogs.com/phile/p/4473085.html
Copyright © 2020-2023  润新知