• 【BZOJ2874】训练士兵(主席树)


    题意:有一个N*M的矩阵,给出一些形如(x1,y1,x2,y2,s)的操作,代表(x1,y1)到(x2,y2)都被加上了s这个数

    现在有一些强制在线的询问,询问(x1,y1)到(x2,y2)的和

    对于100%的数据 n,m<=10^8,k<=40000,q<=100000; 

    思路:将操作(x1,y1,x2,y2,s)差分成

    (x1,y1)+s

    (x1,y2+1)-s

    (x2+1,y1)-s

    (x2+1,y2+1)+s 

    四个点

    询问(x,y)等价于

    [sum_{i=1}^x  sum_{j=1}^y   a[i,j]*(x+1)*(y+1)-a[i,j]*i*(y+1)-a[i,j]*j*(x+1)+a[i,j]*i*j ]

    证明如下:

    可以看出只需维护a[i,j],a[i,j]*i,a[i,j]*j,a[i,j]*i*j四个值的二维前缀和

    从左到右,从上到下排序并离散化,对每一行建立一棵主席树表示左上角的前缀和,

    询问时在主席树中查找一段从头开始的前缀和即可

      1 var t:array[0..6000000,1..6]of int64;
      2     root:array[0..600000]of int64;
      3     c:array[1..300000,1..3]of int64;
      4     cx,cy:array[1..300000]of int64;
      5     n,m,i,j,u,k,cnt,u1,u2,k1,q1,tmp,x,y:longint;
      6     ans,x1,y1,x2,y2:int64;
      7 
      8 procedure swap(var x,y:int64);
      9 var t:int64;
     10 begin
     11  t:=x; x:=y; y:=t;
     12 end;
     13 
     14 procedure qsortx(l,r:longint);
     15 var i,j,mid:longint;
     16 begin
     17  i:=l; j:=r; mid:=cx[(l+r)>>1];
     18  repeat
     19   while mid>cx[i] do inc(i);
     20   while mid<cx[j] do dec(j);
     21   if i<=j then
     22   begin
     23    swap(cx[i],cx[j]);
     24    inc(i); dec(j);
     25   end;
     26  until i>j;
     27  if l<j then qsortx(l,j);
     28  if i<r then qsortx(i,r);
     29 end;
     30 
     31 procedure qsorty(l,r:longint);
     32 var i,j,mid:longint;
     33 begin
     34  i:=l; j:=r; mid:=cy[(l+r)>>1];
     35  repeat
     36   while mid>cy[i] do inc(i);
     37   while mid<cy[j] do dec(j);
     38   if i<=j then
     39   begin
     40    swap(cy[i],cy[j]);
     41    inc(i); dec(j);
     42   end;
     43  until i>j;
     44  if l<j then qsorty(l,j);
     45  if i<r then qsorty(i,r);
     46 end;
     47 
     48 function hashx(x:longint):longint;
     49 var l,r,mid,last:longint;
     50 begin
     51  l:=1; r:=u1; last:=0;
     52  while l<=r do
     53  begin
     54   mid:=(l+r)>>1;
     55   if x>=cx[mid] then begin last:=mid; l:=mid+1; end
     56    else r:=mid-1;
     57  end;
     58  exit(last);
     59 end;
     60 
     61 function hashy(x:longint):longint;
     62 var l,r,mid,last:longint;
     63 begin
     64  l:=1; r:=u2; last:=0;
     65  while l<=r do
     66  begin
     67   mid:=(l+r)>>1;
     68   if x>=cy[mid] then begin last:=mid; l:=mid+1; end
     69    else r:=mid-1;
     70  end;
     71  exit(last);
     72 end;
     73 
     74 procedure qsort(l,r:longint);
     75 var i,j,mid1,mid2:longint;
     76 begin
     77  i:=l; j:=r; mid1:=c[(l+r)>>1,1]; mid2:=c[(l+r)>>1,2];
     78  repeat
     79   while (mid1>c[i,1])or((mid1=c[i,1])and(mid2>c[i,2])) do inc(i);
     80   while (mid1<c[j,1])or((mid1=c[j,1])and(mid2<c[j,2])) do dec(j);
     81   if i<=j then
     82   begin
     83    swap(c[i,1],c[j,1]);
     84    swap(c[i,2],c[j,2]);
     85    swap(c[i,3],c[j,3]);
     86    inc(i); dec(j);
     87   end;
     88  until i>j;
     89  if l<j then qsort(l,j);
     90  if i<r then qsort(i,r);
     91 end;
     92 
     93 function query(p,l,r,x,y:longint):int64;
     94 var mid:longint;
     95 begin
     96  if x=0 then exit(0);
     97  if p=0 then exit(0);
     98  if x>=r then exit(t[p,y]);
     99  mid:=(l+r)>>1;
    100  if x<=mid then exit(query(t[p,5],l,mid,x,y))
    101   else exit(t[t[p,5],y]+query(t[p,6],mid+1,r,x,y));
    102 end;
    103 
    104 function ask(x,y:longint):int64;
    105 var x1,y1:longint;
    106 begin
    107  x1:=hashx(x); y1:=hashy(y);
    108  ask:=0;
    109  ask:=ask+query(root[x1],1,u2,y1,1)*(x+1)*(y+1);
    110  ask:=ask-query(root[x1],1,u2,y1,2)*(y+1);
    111  ask:=ask-query(root[x1],1,u2,y1,3)*(x+1);
    112  ask:=ask+query(root[x1],1,u2,y1,4);
    113 end;
    114 
    115 procedure update(var p:int64;l,r,x:longint;v:int64;x1,y1:longint);
    116 var mid:longint;
    117 begin
    118  inc(cnt); t[cnt]:=t[p];
    119  p:=cnt;
    120  t[cnt,1]:=t[cnt,1]+v;
    121  t[cnt,2]:=t[cnt,2]+v*x1;
    122  t[cnt,3]:=t[cnt,3]+v*y1;
    123  t[cnt,4]:=t[cnt,4]+v*x1*y1;
    124  if l=r then exit;
    125  mid:=(l+r)>>1;
    126  if x<=mid then update(t[p,5],l,mid,x,v,x1,y1)
    127   else update(t[p,6],mid+1,r,x,v,x1,y1);
    128 end;
    129 
    130 begin
    131  assign(input,'bzoj2874.in'); reset(input);
    132  assign(output,'bzoj2874.out'); rewrite(output);
    133  readln(n,m,k1,q1);
    134  k:=0;
    135  for i:=1 to k1 do
    136  begin
    137   read(x1); read(x2); read(y1); read(y2); read(tmp);
    138   inc(k); c[k,1]:=x1; c[k,2]:=y1; c[k,3]:=tmp;
    139   inc(k); c[k,1]:=x1; c[k,2]:=y2+1; c[k,3]:=-tmp;
    140   inc(k); c[k,1]:=x2+1; c[k,2]:=y1; c[k,3]:=-tmp;
    141   inc(k); c[k,1]:=x2+1; c[k,2]:=y2+1; c[k,3]:=tmp;
    142   inc(u); cx[u]:=x1; cy[u]:=y1;
    143   inc(u); cx[u]:=x2+1; cy[u]:=y2+1;
    144  end;
    145  qsortx(1,u); qsorty(1,u);
    146  u1:=1;
    147  for i:=2 to u do
    148   if cx[i]<>cx[u1] then begin inc(u1); cx[u1]:=cx[i]; end;
    149  u2:=1;
    150  for i:=2 to u do
    151   if cy[i]<>cy[u2] then begin inc(u2); cy[u2]:=cy[i]; end;
    152 
    153  qsort(1,k);
    154  j:=1;
    155  for i:=1 to u1 do
    156  begin
    157   root[i]:=root[i-1];
    158   while (j<=k)and(hashx(c[j,1])=i) do
    159   begin
    160    update(root[i],1,u2,hashy(c[j,2]),c[j,3],c[j,1],c[j,2]);
    161    inc(j);
    162   end;
    163  end;
    164  for i:=1 to q1 do
    165  begin
    166   readln(x,y);
    167   x1:=ans mod n+1; x2:=(ans+x) mod n+1; if x1>x2 then swap(x1,x2);
    168   y1:=ans mod m+1; y2:=(ans+y) mod m+1; if y1>y2 then swap(y1,y2);
    169   ans:=ask(x2,y2)-ask(x1-1,y2)-ask(x2,y1-1)+ask(x1-1,y1-1);
    170   writeln(ans);
    171  end;
    172  close(input);
    173  close(output);
    174 end.

     

  • 相关阅读:
    mysql在CentOS6.3上安装
    hdfs高可用性(HDFS High Availability)
    如何做个好员工
    lock(3)——更新锁(U)、排它锁(X)、死锁及如何避免死锁
    锁(1)—— 锁粒度和层次结构
    lock(2)——创建及更新表过程中SQL SERVER锁资源分配情况
    HBase体系结构
    HDFS的shell操作
    Windows 使用 net use 命令
    Windows 使用 net 命令简介
  • 原文地址:https://www.cnblogs.com/myx12345/p/6253647.html
Copyright © 2020-2023  润新知