码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2009]虔诚的墓主人

时间:2018-12-15 19:51:29      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:color   mem   set   sig   cst   ios   ring   getchar   sizeof   

 这道题实质上就是:若每个空位的上下左右有$l,r,u,d$个常青树,最后求每个空位的$C(l,k)*C(r,k)*C(u,k)*C(d,k)$的和。

由于实际坐标点很多,而树很少,又因为$k>0$对于没有树的行和列我们都没有必要处理。

所以通过离散化可以将规模转化成$W*W$级别的。

再通过扫描的方式,配合着线段树(树状数组即可,我写的是线段树),就可以将$O(W^2)$的复杂度降到$O(WlogW)$。

此题得解。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 #define re register
  9 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
 10 #define repd(i, a, b) for (re int i = a; i >= b; --i)
 11 #define maxx(a, b) a = max(a, b);
 12 #define minn(a, b) a = min(a, b);
 13 #define LL long long
 14 #define inf (1 << 30)
 15 #define uint unsigned int
 16 
 17 inline int read() {
 18     int w = 0, f = 1; char c = getchar();
 19     while (!isdigit(c)) f = c == - ? -1 : f, c = getchar();
 20     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ 0), c = getchar();
 21     return w * f;
 22 }
 23 
 24 const int maxw = 1e5 + 5;
 25 
 26 struct Seg_Tree {
 27     #define lson (o << 1)
 28     #define rson (o << 1 | 1)
 29     uint v[maxw << 4];
 30     void pushup(int o) {
 31         v[o] = v[lson] + v[rson];
 32     }
 33     void build() {
 34         memset(v, 0, sizeof(v));
 35     }
 36     void update(int o, int l, int r, int p, uint x) {
 37         if (l == r) { v[o] = x; return; }
 38         int mid = l + r >> 1;
 39         if (mid >= p) update(lson, l, mid, p, x);
 40         else update(rson, mid+1, r, p, x);
 41         pushup(o);
 42     }
 43     uint query(int o, int l, int r, int ql, int qr) {
 44         if (ql <= l && r <= qr) return v[o];
 45         int mid = l + r >> 1;
 46         uint ans = 0;
 47         if (ql <= mid) ans += query(lson, l, mid, ql, qr);
 48         if (mid < qr) ans += query(rson, mid+1, r, ql, qr);
 49         return ans;
 50     }
 51 } ST;
 52 
 53 struct Point {
 54     int x, y, p;
 55 } a[maxw];
 56 
 57 int n, m, w, l[maxw], sum[maxw], cnt = 0, k;
 58 
 59 uint ans = 0, C[maxw], mul[10];
 60 
 61 bool cmp1(Point a, Point b) {
 62     return a.x < b.x;
 63 }
 64 
 65 bool cmp2(Point a, Point b) {
 66     return a.y < b.y || a.y == b.y && a.x < b.x;
 67 }
 68 
 69 int main() {
 70     n = read(), m = read();
 71     w = read();
 72 
 73     rep(i, 1, w) a[i] = (Point){read(), read(), 0};
 74 
 75     k = read();
 76 
 77     C[k] = mul[0] = 1;
 78 
 79     rep(i, k+1, maxw) {
 80         uint bit = 0;
 81         rep(x, 0, 9) {
 82             LL s = (LL)mul[x] * i + bit;
 83             mul[x] = s;
 84             bit = (s - mul[x]) >> 32;
 85         }
 86         repd(x, 9, 0) {
 87             LL s = (LL)mul[x] + ((LL)bit << 32);
 88             mul[x] = s / (i - k);
 89             bit = s - (LL)mul[x] * (i - k);
 90         }
 91         C[i] = mul[0];
 92     }
 93 
 94     ST.build();
 95 
 96     sort(a + 1, a + w + 1, cmp1);
 97 
 98     a[0].x = a[0].y = -1;
 99 
100     rep(i, 1, w) {
101         if (a[i].x != a[i-1].x) cnt++;
102         a[i].p = cnt;
103         sum[cnt]++;
104     }
105 
106     sort(a + 1, a + w + 1, cmp2);
107 
108     int s = 1;
109     while (s <= w) {
110         int p = s;
111         while (p < w && a[p+1].y == a[s].y) p++;
112         rep(i, s+1, p) {
113             if (a[i-1].p < a[i].p-1)
114                 ans += ST.query(1, 1, cnt, a[i-1].p+1, a[i].p-1) * C[i-s] * C[p-i+1];
115         }
116         rep(i, s, p) {
117             l[a[i].p]++;
118             ST.update(1, 1, cnt, a[i].p, C[l[a[i].p]] * C[sum[a[i].p] - l[a[i].p]]);
119         }
120         s = p + 1;
121     }
122 
123     printf("%lu", ans % 2147483648);
124 
125     return 0;
126 }

 

[SDOI2009]虔诚的墓主人

标签:color   mem   set   sig   cst   ios   ring   getchar   sizeof   

原文地址:https://www.cnblogs.com/ac-evil/p/10124256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!