过了一周,终于迎来了第二次模拟(这不是期待的语气),看第一周毒瘤程度,我就觉得接下来的模拟只能更毒瘤。

 

花了10多分钟读完了三道题,觉得暴力还是挺好写的,然后在每一道题都思索那么几分钟后,觉得还是写暴力靠谱一些……不过还好,一个半点就把暴力都写完了。

然后我就接着想正解……

T1 game

  这道题刚开始就觉得是二维线段树,然后瞟了一眼数据范围:1e6 * 1e6,于是就犹豫了。就一直在想能不能行和列各只开一个线段树,最终反正是没想出来,于是开始优化我的暴力。推了半天发现了一个惊天秘密:就是修改的顺序是可以颠倒的:于是我就先O(n)处理了所有行的修改,然后对于所有列的修改,再暴力的O(n2)修改:所以说,只要这个数据行的修改越多,我就越容易拿掉80的点……后来经过【地表最强】lsy的山寨数据测了一下,发现还是稳稳的40分……

  暴力以及考场心路历程就说到这吧,该讲讲正解是啥咧。

  嗯……概括一下,就是这题没A就是数列没学好。

  我们开一个lzy_rol[n], lzy_lin[m]两个标记数组,记录每一行或是每一列要乘上多少。假设我们没有列的操作,那么一列看成一个数,整张图就是一个长度为m的等差数列,不想O(1)的话O(m)就能求出来。现在加上了列的操作。其实就是对于每一个数ai乘上了一个lzy_lin[i],只要按顺序算到ai,然后答案加上ai * lzy_lin[i]就行了…………

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const ll mod = 1e9 + 7;
21 const int maxn = 1e6 + 5;
22 inline ll read()
23 {
24     ll ans = 0;
25     char ch = getchar(), last = ' ';
26     while(!isdigit(ch)) {last = ch; ch = getchar();}
27     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
28     if(last == '-') ans = -ans;
29     return ans;
30 }
31 inline void write(ll x)
32 {
33     if(x < 0) x = -x, putchar('-');
34     if(x >= 10) write(x / 10);
35     putchar(x % 10 + '0');
36 }
37 
38 int n, m, q; 
39 char c[5];
40 ll lzy_rol[maxn], lzy_lin[maxn]; 
41 ll s = 0, d = 0, sum = 0;
42 
43 ll getnum(int x, int i)
44 {
45     return ((ll)(i - 1) * m + x) % mod;
46 }
47 
48 int main()
49 {
50     freopen("game.in", "r", stdin);
51     freopen("game.out", "w", stdout);
52     n = read(); m = read(); q = read();
53     for(int i = 1; i < maxn; ++i) lzy_rol[i] = lzy_lin[i] = 1;
54     for(int i = 1; i <= q; ++i)
55     {
56         scanf("%s", c); int x = read(); ll k = read();
57         if(c[0] == 'R') lzy_rol[x] *= k, lzy_rol[x] %= mod;    
58         else lzy_lin[x] *= k, lzy_lin[x] %= mod;
59     }
60     for(int i = 1; i <= n; ++i)
61     {
62         s += getnum(1, i) * lzy_rol[i]; s %= mod;
63         d += lzy_rol[i]; d %= mod;
64     }                            //s:首项,d:公差 
65     for(rg int i = 1; i <= m; ++i)        
66     {
67         sum += lzy_lin[i] * s; sum %= mod;
68         s += d; s %= mod;
69     }
70     write(sum); enter;
71     return 0;
72 }
View Code

相关文章:

  • 2021-11-25
  • 2021-11-18
  • 2021-11-23
  • 2021-10-04
  • 2022-12-23
  • 2021-08-18
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-04-15
  • 2021-04-10
  • 2022-12-23
  • 2022-12-23
  • 2021-09-01
相关资源
相似解决方案