zoukankan      html  css  js  c++  java
  • 【以前的空间】bzoj 1227 [SDOI2009]虔诚的墓主人

    题解:hzw大神的博客说的很清楚嘛

    http://hzwer.com/1941.html

        朴素的做法就是每个点如果它不是墓地那么就可形成十字架的数量就是这个c(点左边的树的数量,k)*c(点右边的树的数量,k)*c(点上边的树的数量,k)*c(点下边的树的数量,k)。这样的话要枚举每个点,复杂度很明显爆表。

        再仔细分析一下,其实完全可以不用枚举每个点,只需要枚举那些树的位置就可以,(下面的点指的都是树而非点??蒟蒻语言不好)在同一列的两棵相邻的树之间的点的c(点左边的树的数量,k)*c(点右边的树的数量,k)是一样的,但是还是需要Σc(点上边的树的数量,k)*c(点下边的树的数量,k)(乘法分配率,自己yy一下),朴素枚举这些还是要复杂度爆表,于是问题就是如果在logn时间内搞定这个东西,于是想到如果维护“Σc(点上边的树的数量,k)*c(点下边的树的数量,k)”的信息(询问区间和,想到树状数组或者线段树),(有点类似于那个悬梁法)就是这个点的上一个点和这个点之间的“c(点上边的树的数量,k)*c(点下边的树的数量,k)”是有一点联系的,yy一下就是这个点在下一行中是作为下面的点上面的树的数量……于是修改量就是c(原来上边的树的数量+1,k)*c(原来下边的树(其实包括了这个点也就是这棵树)的数量-1,k)- c(原来上边的树的数量,k)*c(原来下边的树(其实包括了这个点也就是这棵树)的数量,k)。

      然后只需要在一开始离散化一下树,再给树排个序,就差不多了,还用到了前缀和小小的搞一下。

    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    type
      arr=record
        x,y:longint;
      end;
     
    const
      mm=2147483648;
     
    var
      i,j,kk,l,n,m,w,now,tot:longint;
      a:array[0..100500]of arr;
      bit:array[0..400000]of int64;
      b,d,totx,toty,hash:array[0..400000]of longint;
      c:array[0..100500,0..11]of int64;
      ans,ans1,ans2,ans3:int64;
     
    procedure swap(var x,y:longint);
    var
      i:longint;
    begin
      i:=x;
      x:=y;
      y:=i
    end;
     
    function min(x,y:longint):longint;
    begin
      if x>y then exit(y);
      exit(x)
    end;
     
    function lowbit(x:longint):longint;
    begin
      exit(x and (-x))
    end;
     
    function find(x:longint):longint;
    var
      l,r,mid:longint;
    begin
      l:=1;r:=tot;
      while l<=r do begin
        mid:=(l+r) >> 1;
        if hash[mid]<x then l:=mid+1
          else
            if hash[mid]>x then r:=mid-1
              else exit(mid);
      end
    end;
     
    procedure work;
    var
      i,j:longint;
    begin
      c[0][0]:=1;
      for i:=1 to w do begin
        c[i,0]:=1;
        for j:=1 to min(kk,i) do
          c[i,j]:=(c[i-1,j]+c[i-1,j-1]) mod mm;
      end
    end;
     
    procedure qsort1(l,r:longint);
    var
      i,j,k,mid:longint;
    begin
      i:=l;
      j:=r;
      mid:=b[(l+r) >>1];
      repeat
        while b[i]<mid do inc(i);
        while b[j]>mid do dec(j);
        if i<=j then begin
          swap(b[i],b[j]);
          inc(i);
          dec(j);
        end;
      until i>j;
      if l<j then qsort1(l,j);
      if i<r then qsort1(i,r)
    end;
     
    procedure qsort2(l,r:longint);
    var
      i,j,k,mid1,mid2:longint;
    begin
      i:=l;
      j:=r;
      mid1:=a[(l+r) >>1].y;
      mid2:=a[(l+r) >>1].x;
      repeat
        while (a[i].y<mid1) or (a[i].y=mid1) and (a[i].x<mid2) do inc(i);
        while (a[j].y>mid1) or (a[j].y=mid1) and (a[j].x>mid2) do dec(j);
        if i<=j then begin
          swap(a[i].x,a[j].x);
          swap(a[i].y,a[j].y);
          inc(i);
          dec(j);
        end;
      until i>j;
      if l<j then qsort2(l,j);
      if i<r then qsort2(i,r)
    end;
     
     
     
    procedure add(x:longint;y:int64);
    begin
      while x<=tot do begin
        bit[x]:=(bit[x]+y) mod mm;
        inc(x,lowbit(x));
      end
    end;
     
    function ask(x:longint):int64;
    var
      sum:int64;
    begin
      sum:=0;
      while x>0 do begin
        sum:=(sum+bit[x]) mod mm;
        dec(x,lowbit(x));
      end;
      exit(sum)
    end;
     
    begin
      readln(n,m);
      readln(w);
      fillchar(totx,sizeof(totx),0);
      fillchar(toty,sizeof(toty),0);
      fillchar(d,sizeof(d),0);
      fillchar(bit,sizeof(bit),0);
      fillchar(c,sizeof(c),0);
      fillchar(hash,sizeof(hash),0);
      for i:=1 to w do begin
        read(a[i].x,a[i].y);
        b[2*i-1]:=a[i].x;
        b[2*i]:=a[i].y;
      end;
      qsort1(1,2*w);
      hash[1]:=b[1];
      tot:=1;
      for i:=2 to 2*w do
        if b[i]<>b[i-1] then begin
          inc(tot);
          hash[tot]:=b[i];
        end;
      read(kk);
      work;
      for i:=1 to w do begin
        inc(totx[find(a[i].y)]);
        inc(toty[find(a[i].x)]);
      end;
      qsort2(1,w);
      now:=0;
      ans:=0;
      for i:=1 to w do begin
        j:=find(a[i].x);
        if (i>1) and (a[i].y=a[i-1].y) then begin
          inc(now);
          ans1:=ask(j-1)-ask(find(a[i-1].x)) mod mm;
          ans2:=c[now,kk]*c[totx[find(a[i].y)]-now,kk] mod mm;
          ans:=(ans+ans1*ans2) mod mm;
        end else now:=0;
        inc(d[j]);
        ans3:=(c[d[j],kk]*c[toty[j]-d[j],kk]-c[d[j]-1,kk]*c[toty[j]-d[j]+1,kk])mod mm;
        if ans3<>0 then add(j,ans3);
      end;
      if ans<0 then ans:=ans+mm;
      writeln(ans);
    end.
    View Code
  • 相关阅读:
    ant+jmeter 报告优化
    使用no-gui 模式执行分布式测试
    jmeter 4.0使用本机做slave
    jmeter 4.0,分布式测试
    jmeter 跨线程执行变量
    jmeter if 控制器
    jmeter 获取cookie
    jmeter 使用 P函数 自动控制ip和端口等变量
    linux 配置tomcat环境变量
    linux 配置jdk环境变量
  • 原文地址:https://www.cnblogs.com/Macaulish/p/6492084.html
Copyright © 2011-2022 走看看