过了一周,终于迎来了第二次模拟(这不是期待的语气),看第一周毒瘤程度,我就觉得接下来的模拟只能更毒瘤。
花了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 }