涂鸦* CCPC wannafly

题目描述

 

九条可怜收到了一块神奇的画板。

画板被划分成了 nn 行 mm 列一共 n \times mn×m 个格子,记第 ii 行第 jj 列的格子的坐标为 (i,j)(i,j)。画板的每一行有属性 l_i,r_i(1 \leq l_i \leq r_i \leq m)li,ri(1lirim),代表了 [1,m][1,m] 的一个子区间。

画板有一个开始按钮,在按下开始按钮之后,画板会自动初始化颜色:对于第 ii 行,画板会从 [l_i,r_i][li,ri] 的 \frac{(r_i-l_i+1)(r_i-l_i+2)}{2}2(rili+1)(rili+2) 个子区间中,独立地等概率地选择一个涂黑。举例来说,如果 i=1,[l_i,r_i]=[1,2]i=1,[li,ri]=[1,2],那么它一共有 33 个子区间 [1,2],[1,1][1,2],[1,1] 和 [2,2][2,2],他们各有 \frac{1}{3}31 的概率被选中,因此格子 (1,1),(1,2)(1,1),(1,2) 都有 \frac{2}{3}32的概率被染黑。

在画板初始化结束后,可怜选择了 qq 个矩形,第 ii 个矩形包含了所有满足 a \in [lx_i,rx_i], b \in [ly_i,ry_i]a[lxi,rxi],b[lyi,ryi] 的格子 (a,b)(a,b)。接着可怜会把至少被一个矩形包含的格子给涂白(如果原来就是白色则颜色不变)。

可怜重复上述过程若干次,渐渐地感到了无聊。为了让事情更有趣一些,她想要计算,在给出这 qq 个矩形的情况下,绘画结束后画板上黑色格子数量的期望是多少。

 

 
 

输入描述

 

第一行三个整数 n,m,q(1 \leq n,m \leq 10^3,1 \leq q \leq 2 \times 10^5)n,m,q(1n,m103,1q2×105)。

接下来 nn 行每行两个整数 l_i,r_i(1 \leq l_i \leq r_i \leq m)li,ri(1lirim),表示第 ii 行的属性。

接下来 qq 行每行四个整数 lx_i,ly_i,rx_i,ry_i(1 \leq lx_i \leq rx_i \leq n, 1 \leq ly_i \leq ry_i \leq m)lxi,lyi,rxi,ryi(1lxirxin,1lyiryim),表示一个矩形。

 

输出描述

 

输出一行一个整数表示答案,棋盘上黑色格子数量的期望对 998244353998244353 取模后的结果。即,如果答案的最简分数表示为 \frac{x}{y}yx,输出 x \times y^{-1} \mod 998244353x×y1mod998244353。

 

样例输入 1 

4 4 1
1 3
2 4
3 4
1 4
2 2 3 3

样例输出 1

831870299





对于某一个点来说,它被染成黑点的概率是(xl+1)(rx+1)2(rl+1)(rl+2)(x−l+1)⋅(r−x+1)⋅2(r−l+1)⋅(r−l+2) 

然后二维BIT维护矩形,最后将所有未被矩形覆盖的期望加起来即可。

BIT本身维护的就是一个前缀和,所以说在查询每个点的被覆盖的次数的时候

只需查询这一个点即可。





 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1010
 6 const ll p = (ll)998244353;
 7 const ll MOD = (ll)998244353;
 8 int n, m, q;
 9 ll inv[N];
10 int ans[N][N];
11 
12 namespace BIT
13 {
14     int a[N][N];
15     void init() { memset(a, 0, sizeof a); }
16     void update(int x, int y, int v)
17     {
18        // for (int i = x; i > 0; i -= i & -i)
19                     for (int i = x; i <=n ; i += i & -i)
20                             for (int j = y; j <=m; j += j & -j)
21 
22           //  for (int j = y; j > 0; j -= j & -j)
23                 a[i][j] += v;
24     }
25     int query(int x, int y)
26     {
27         int res = 0;
28       //  for (int i = x; i < N; i += i & -i)
29             for(int i=x;i;i-=i&(-i))
30                 for(int j=y;j;j-=j&(-j))
31                  res += a[i][j];
32           //  for (int j = y; j < N; j += j & -j)
33     //   cout<<"que: "<<x<<" "<<y<<" " <<res<<endl;
34         return res;
35     }
36     void update(int x1, int y1, int x2, int y2)
37     {
38       /*  update(x1 - 1, y1 - 1, 1);
39         update(x1 - 1, y2, -1);
40         update(x2, y1 - 1, -1);
41         update(x2, y2, 1);
42 
43         */
44 
45 
46         update(x1, y1, 1);
47         update(x1 , y2+1, -1);
48                 update(x2+1, y1 , -1);
49          update(x2 +1, y2 +1, 1);
50 
51     }
52 }
53 
54 int main()
55 {
56     inv[1] = 1;
57     for (int i = 2; i < N; ++i) inv[i] = inv[p % i] * (p - p / i) % p;
58     while (scanf("%d%d%d", &n, &m, &q) != EOF)
59     {
60         memset(ans, 0, sizeof ans); BIT::init();
61         for (int i = 1, l, r; i <= n; ++i)
62         {
63             scanf("%d%d", &l, &r);
64             for (int j = l; j <= r; ++j)
65                 ans[i][j] = 2ll * (j - l + 1) %p * (r - j + 1) %p * inv[r - l + 1] % p * inv[r - l + 2] % p;
66             //cout << ans[i][l] * (r - l + 1) * (r - l + 2) / 2 % p << endl;
67         }
68         for (int qq = 1; qq <= q; ++qq)
69         {
70             int x1, x2, y1, y2;
71             scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
72             BIT::update(x1, y1, x2, y2);
73         }
74         ll res = 0;
75 
76    /*     for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j)
77         {
78              int t=BIT::query(i,j);
79             cout<<i<<" "<<j<<" "<<t<<endl;
80         }*/
81         for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j)
82         {
83             int t=BIT::query(i,j);//-BIT::query(i-1,j)-BIT::query(i,j-1)+BIT::query(i-1,j-1);
84            // cout<<i<<" "<<j<<" "<<t<<endl;
85             if (!t)
86         {
87            // cout << i << " " << j << endl;
88             res = (res + ans[i][j]) % p;
89         }
90 
91 
92         }
93         printf("%lld\n", res);
94 
95     }
96     return 0;
97 }













猜你喜欢

转载自www.cnblogs.com/zhangbuang/p/10907513.html
今日推荐