zoukankan      html  css  js  c++  java
  • 1176: [Balkan2007]Mokia

    Description
    维护一个W*W的矩阵,每次操作可以增加某格子的权值,或询问某子矩阵的总权值。 修改操作数M<=160000,询问数Q<=10000,W<=2000000。
    Input
    Output
    Sample Input
    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3
    Sample Output
    3
    5
    HINT

    Input file Output file Meaning
    0 4 Table size is , filled with zeroes.

    1 2 3 3 Add 3 customers at (2, 3).
    2 1 1 3 3 Query sum of rectangle , .

    3 Answer.
    1 2 2 2 Add 2 customers at (2, 2).
    2 2 2 3 4 Query sum of rectangle , .

    5 Answer
    3 Exit your program.

    题目大意:给你一个矩阵,每次可以增加一个点的权值,或者询问一个子矩阵的和

    cdq分治

    先做一个预处理,把每一个询问(x1,y1)(x2,y2)变成(1,y1)(x,y2)的形式,其实只要拆成两个相减的形式就行了

    把询问(x1,y1)(x2,y2)改成(1,y1)(x1-1,y2)和(1,y1)(x2,y2)两个询问,回答的时候只要做差就行了

    考虑什么操作才会对询问做出贡献,当这个操作time比询问早,操作的x<=询问的x才会有贡献

    所以我们先按time排序,其实都不用排了

    保证只有前面的才会影响后面的,然后对这些操作和询问进行(按x为关键字)归并排序

    每次合并的时候计算出左边区间对右边区间造成的影响

    所以slove函数就是这样的

    1 procedure slove(l,r:longint);
    2 var
    3     mid:longint;
    4 begin
    5     if l=r then exit;
    6     slove(l,mid);
    7     slove(mid+1,r);
    8     merge(l,mid,mid+1,r);
    9 end;

    基本上就是这样了

      1 const
      2     maxn=200000;
      3     maxq=20010;
      4     maxw=2000010;
      5 type
      6     node=record
      7       q:boolean;
      8       x,l,r,k:longint;
      9       ans:int64;
     10     end;
     11 
     12 var
     13     add,n,numq,m:longint;
     14     a,b:array[0..maxn*2]of node;
     15     ans:array[0..maxq]of int64;
     16 
     17 procedure init;
     18 var
     19     k,x1,y1,x2,y2:longint;
     20 begin
     21     read(add,n);
     22     while true do
     23       begin
     24         read(k);
     25         if k=3 then exit;
     26         if k=1 then
     27           begin
     28             inc(m);
     29             with a[m] do
     30               read(x,l,r);
     31           end
     32         else
     33           begin
     34             read(x1,y1,x2,y2);
     35             inc(m);inc(numq);
     36             with a[m] do
     37               begin
     38                 k:=numq;
     39                 q:=true;
     40                 x:=x1-1;
     41                 l:=y1;r:=y2;
     42               end;
     43             inc(m);inc(numq);
     44             with a[m] do
     45               begin
     46                 k:=numq;
     47                 q:=true;
     48                 x:=x2;
     49                 l:=y1;r:=y2;
     50               end;
     51           end;
     52       end;
     53 end;
     54 
     55 var
     56     time:longint;
     57     vis:array[0..maxw]of longint;
     58     c:array[0..maxw]of int64;
     59 
     60 function lowbit(x:longint):longint;
     61 begin
     62     exit(x and -x);
     63 end;
     64 
     65 procedure insert(x:longint;y:int64);
     66 begin
     67     while x<=n do
     68       begin
     69         if vis[x]<>time then
     70         begin
     71           vis[x]:=time;
     72           c[x]:=0;
     73         end;
     74         inc(c[x],y);
     75         inc(x,lowbit(x));
     76       end;
     77 end;
     78 
     79 function sum(x:longint):int64;
     80 begin
     81     sum:=0;
     82     while x>0 do
     83       begin
     84         if vis[x]<>time then
     85         begin
     86           vis[x]:=time;
     87           c[x]:=0;
     88         end;
     89         inc(sum,c[x]);
     90         dec(x,lowbit(x));
     91       end;
     92 end;
     93 
     94 procedure slove(l,r:longint);
     95 var
     96     mid,i,j,k,x:longint;
     97 begin
     98     if l=r then exit;
     99     mid:=(l+r)>>1;
    100     slove(l,mid);
    101     slove(mid+1,r);
    102     x:=l;
    103     i:=l;
    104     j:=mid+1;
    105     inc(time);
    106     while (i<=mid) and (j<=r) do
    107       begin
    108         if a[i].x<=a[j].x then k:=i
    109         else k:=j;
    110         if (k<=mid) and (a[k].q=false) then insert(a[k].l,a[k].r);
    111         if (k>mid) and (a[k].q) then inc(a[k].ans,sum(a[k].r)-sum(a[k].l-1));
    112         if k=i then inc(i)
    113         else inc(j);
    114         b[x]:=a[k];
    115         inc(x);
    116       end;
    117     while i<=mid do
    118       begin
    119         b[x]:=a[i];
    120         inc(i);
    121         inc(x);
    122       end;
    123     while j<=r do
    124       begin
    125         if a[j].q then
    126         inc(a[j].ans,sum(a[j].r)-sum(a[j].l-1));
    127         b[x]:=a[j];
    128         inc(j);
    129         inc(x);
    130       end;
    131     for i:=l to r do
    132       a[i]:=b[i];
    133 end;
    134 
    135 procedure work;
    136 var
    137     i:longint;
    138 begin
    139     slove(1,m);
    140     for i:=1 to m do
    141       if a[i].q then
    142       ans[a[i].k]:=a[i].ans+add*a[i].x*(a[i].r-a[i].l+1);
    143     for i:=1 to numq>>1 do
    144       writeln(ans[i<<1]-ans[i<<1-1]);
    145 end;
    146 
    147 begin
    148     init;
    149     work;
    150 end.
    ACcode
  • 相关阅读:
    实现Maven自动下载源代码包并关联
    Maven3入门篇
    小典故:为什么数组的索引总是从0开始,而不是1?
    C语言算法探究之(一):算法的准确性
    C语言算法探究之(二):算法的准确性
    Visual Studio对无用引用(unused using)的处理方法
    C# CRC8的实现(原创)
    C#4.0:新功能和展望
    C#控件重绘学习(一)
    双加号(++)在C#中的用法解释
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3626029.html
Copyright © 2011-2022 走看看