• 【ZJOI2017 Round2练习&BZOJ4826】D1T2 sf(主席树,单调栈)


    题意:

    思路:From http://blog.csdn.net/neither_nor/article/details/70211150

    对每个点i,单调栈求出左边和右边第一个大于i的位置,记为l[i]和r[i]

    那么(l[i],r[i])会产生p1的贡献

    左端点为l[i],右端点在[i+1,r-1]的点对都会产生p1的贡献

    右端点为r[i],左端点在[l+1,i-1]的点对都会产生p2的贡献

    将点对看成平面上的点,横坐标左端点纵坐标右端点,上述贡献分别对应单点加和线段加

    查询就是矩形求和

    From MG:

    考虑修改均为如(x,y1..y2)与(x1..x2,y)形式

    因为询问均为矩形,则修改(y1..y2,x)与(x,y1..y2)等价

    若统一转化为(x,y1..y2)形式,可用主席树维护

    若统一转化为(y1..y2,x)形式,可用树状数组套主席树维护

    注意点对(i,i)都有p1的贡献

      1 var t:array[0..10000000]of record
      2                            a,s:int64;
      3                            l,r:longint;
      4                           end;
      5     d:array[1..1000000,1..4]of longint;
      6     l,r:array[1..300000]of longint;
      7     root,stk,a:array[0..300000]of longint;
      8     n,m,i,cnt,j,top,que,x,y,p1,p2:longint;
      9     ans:int64;
     10 
     11 procedure update(l,r,x,y,v:longint;var p:longint);
     12 var mid:longint;
     13 begin
     14  if (l>x)or(x>y) then exit;
     15  inc(cnt); t[cnt]:=t[p]; p:=cnt;
     16  t[p].s:=t[p].s+int64(v)*(y-x+1);
     17  if (l=x)and(r=y) then
     18  begin
     19   t[p].a:=t[p].a+v;
     20   exit;
     21  end;
     22  mid:=(l+r)>>1;
     23  if y<=mid then update(l,mid,x,y,v,t[p].l)
     24   else if x>mid then update(mid+1,r,x,y,v,t[p].r)
     25   else
     26   begin
     27    update(l,mid,x,mid,v,t[p].l);
     28    update(mid+1,r,mid+1,y,v,t[p].r);
     29   end;
     30 end;
     31 
     32 procedure query(l,r,x,y,p1,p2:longint);
     33 var mid:longint;
     34 begin
     35  if (l=x)and(r=y) then
     36  begin
     37   ans:=ans+t[p1].s-t[p2].s;
     38   exit;
     39  end;
     40  ans:=ans+(t[p1].a-t[p2].a)*(y-x+1);
     41  mid:=(l+r)>>1;
     42  if y<=mid then query(l,mid,x,y,t[p1].l,t[p2].l)
     43   else if x>mid then query(mid+1,r,x,y,t[p1].r,t[p2].r)
     44   else
     45   begin
     46    query(l,mid,x,mid,t[p1].l,t[p2].l);
     47    query(mid+1,r,mid+1,y,t[p1].r,t[p2].r);
     48   end;
     49 end;
     50 
     51 procedure swap(var x,y:longint);
     52 var t:longint;
     53 begin
     54  t:=x; x:=y; y:=t;
     55 end;
     56 
     57 procedure qsort(l,r:longint);
     58 var i,j,mid:longint;
     59 begin
     60  i:=l; j:=r; mid:=d[(l+r)>>1,1];
     61  repeat
     62   while mid>d[i,1] do inc(i);
     63   while mid<d[j,1] do dec(j);
     64   if i<=j then
     65   begin
     66    swap(d[i,1],d[j,1]);
     67    swap(d[i,2],d[j,2]);
     68    swap(d[i,3],d[j,3]);
     69    swap(d[i,4],d[j,4]);
     70    inc(i); dec(j);
     71   end;
     72  until i>j;
     73  if l<j then qsort(l,j);
     74  if i<r then qsort(i,r);
     75 end;
     76 
     77 begin
     78  assign(input,'bzoj4826.in'); reset(input);
     79  assign(output,'bzoj4826.out'); rewrite(output);
     80  readln(n,que,p1,p2);
     81  for i:=1 to n do read(a[i]);
     82  top:=1; stk[top]:=0; a[0]:=maxlongint;
     83  for i:=1 to n do
     84  begin
     85   while (top>0)and(a[i]>a[stk[top]]) do dec(top);
     86   if top=1 then l[i]:=0
     87    else l[i]:=stk[top];
     88   inc(top); stk[top]:=i;
     89  end;
     90  top:=1; stk[top]:=n+1; a[n+1]:=maxlongint;
     91  for i:=n downto 1 do
     92  begin
     93   while (top>0)and(a[i]>a[stk[top]]) do dec(top);
     94   if top=1 then r[i]:=n+1
     95    else r[i]:=stk[top];
     96   inc(top); stk[top]:=i;
     97  end;
     98  for i:=1 to n do
     99  begin
    100   if (l[i]>0)and(r[i]<=n) then
    101   begin
    102    inc(m); d[m,1]:=l[i]; d[m,2]:=r[i]; d[m,3]:=r[i]; d[m,4]:=p1;
    103   end;
    104   if l[i]>0 then
    105   begin
    106    inc(m); d[m,1]:=l[i]; d[m,2]:=i+1; d[m,3]:=r[i]-1; d[m,4]:=p2;
    107   end;
    108   if r[i]<=n then
    109   begin
    110    inc(m); d[m,1]:=r[i]; d[m,2]:=l[i]+1; d[m,3]:=i-1; d[m,4]:=p2;
    111   end;
    112  end;
    113  qsort(1,m);
    114  j:=1;
    115  for i:=1 to n do
    116  begin
    117   root[i]:=root[i-1];
    118   while (j<=m)and(d[j,1]=i) do
    119   begin
    120    update(1,n,d[j,2],d[j,3],d[j,4],root[i]);
    121    inc(j);
    122   end;
    123  end;
    124  for i:=1 to que do
    125  begin
    126   readln(x,y);
    127   ans:=(y-x)*p1;
    128   query(1,n,x,y,root[y],root[x-1]);
    129   writeln(ans);
    130  end;
    131  close(input);
    132  close(output);
    133 end.
  • 相关阅读:
    redis该怎么用
    cookie和session的比较
    web常见攻击
    请大神指导从大日志文件中统计关键字次数的办法
    apache中 MaxClients 与MaxRequestsPerChild
    如何提高缓存命中率
    CSU-ACM2018暑假集训比赛1
    CodeForces
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/myx12345/p/6731938.html
Copyright © 2020-2023  润新知