【ZJOI2017 Round1练习】D2T3 counter(线段树)

题意:

思路:

预处理出b[i]代表i位置之前比a[i]小的数的个数

以每个数为结尾的组数是线段树中(1,a[i]-1)

对于a[i]换到最后,相当于线段树中(a[i]+1,n)--

交换后b[i]又变成了a[i]-1因为换到最后不需要考虑位置只需要考虑大小关系

  1 var t:array[1..1000000]of record
  2                            a,s,l:int64;
  3                           end;
  4     a,b:array[1..500000]of longint;
  5     n,m,i:longint;
  6     ans,s:int64;
  7 
  8 procedure pushdown(p:longint);
  9 var l,r:longint;
 10     tmp:int64;
 11 begin
 12  l:=p<<1; r:=l+1;
 13  tmp:=t[p].a;
 14  if tmp=0 then exit;
 15  t[l].a:=t[l].a+tmp;
 16  t[r].a:=t[r].a+tmp;
 17  t[l].s:=t[l].s+t[l].l*tmp;
 18  t[r].s:=t[r].s+t[r].l*tmp;
 19  t[p].a:=0;
 20 end;
 21 
 22 procedure pushup(p:longint);
 23 begin
 24  t[p].s:=t[p<<1].s+t[p<<1+1].s;
 25 end;
 26 
 27 function query(l,r,x,y,p:longint):int64;
 28 var mid:longint;
 29 begin
 30  if x>y then exit(0);
 31  if (l>=x)and(r<=y) then exit(t[p].s);
 32  pushdown(p);
 33  mid:=(l+r)>>1;
 34  query:=0;
 35  if x<=mid then query:=query+query(l,mid,x,y,p<<1);
 36  if y>mid then query:=query+query(mid+1,r,x,y,p<<1+1);
 37  pushup(p);
 38 end;
 39 
 40 procedure update(l,r,x,y,v,p:longint);
 41 var mid:longint;
 42 begin
 43  if x>y then exit;
 44  if (l>=x)and(r<=y) then
 45  begin
 46   t[p].s:=t[p].s+t[p].l*v;
 47   t[p].a:=t[p].a+v;
 48   exit;
 49  end;
 50  pushdown(p);
 51  mid:=(l+r)>>1;
 52  if x<=mid then update(l,mid,x,y,v,p<<1);
 53  if y>mid then update(mid+1,r,x,y,v,p<<1+1);
 54  pushup(p);
 55 end;
 56 
 57 procedure build(l,r,p:longint);
 58 var mid:longint;
 59 begin
 60  t[p].l:=r-l+1;
 61  if l=r then
 62  begin
 63   t[p].s:=b[l];
 64   exit;
 65  end;
 66  mid:=(l+r)>>1;
 67  build(l,mid,p<<1);
 68  build(mid+1,r,p<<1+1);
 69  pushup(p);
 70 end;
 71 
 72 procedure change(l,r,x,v,p:longint);
 73 var mid:longint;
 74 begin
 75  if l=r then
 76  begin
 77   t[p].a:=0; t[p].s:=v;
 78   exit;
 79  end;
 80  pushdown(p);
 81  mid:=(l+r)>>1;
 82  if x<=mid then change(l,mid,x,v,p<<1)
 83   else change(mid+1,r,x,v,p<<1+1);
 84  pushup(p);
 85 end;
 86 
 87 begin
 88  assign(input,'counter.in'); reset(input);
 89  assign(output,'counter.out'); rewrite(output);
 90  readln(n);
 91  build(1,n,1);
 92  for i:=1 to n do
 93  begin
 94   read(a[i]);
 95   b[a[i]]:=query(1,n,1,a[i]-1,1);
 96   update(1,n,a[i],a[i],1,1);
 97  end;
 98  fillchar(t,sizeof(t),0);
 99  build(1,n,1);
100  for i:=1 to n do
101  begin
102   s:=query(1,n,1,a[i]-1,1);
103   ans:=ans+s;
104   update(1,n,a[i]+1,n,-1,1);
105   s:=a[i]-1;
106   change(1,n,a[i],s,1);
107  end;
108  writeln(ans);
109 
110  close(input);
111  close(output);
112 end.

 

posted on 2017-03-01 21:12  myx12345  阅读(168)  评论(0编辑  收藏  举报

导航