emmmm......ouuan大佬上紫了,我卻沒打......c++
首先吐槽一波家長會和機房鎖門,害我只能來打虛擬賽。ide
寫了abcd四題,仍是被ouuan大佬吊打.......spa
264名,應該能上分吧。3d
A,你要作n張賀卡,每張賀卡須要2紅,5黃,8藍。code
你買一張卡紙就能得到k個某種顏色。問最少買幾張卡紙。blog
解:紅色就是(2*n-1)/k+1,別的以此類推。it
B,給你個數列,ai=i*(-1)^i,求L到R的和。event
解:咱們先兩兩求和,最後可能有多出來的,處理一下。class
C,給你個n*m的矩陣,黑白染色。先把一塊染成白色,又把一塊染成黑色。求最終的黑色個數。cli
解:先分開處理,而後把交叉的地方的黑色加上。
D,題意比較複雜......
能夠想到一種貪心就是先儘可能切邊緣的一條小道,直到剩餘刀數不夠。
而後判斷別的地方空出來的能不能放下全部剩餘刀數。
轉化一下就是把別的地方都切了,看刀數是否是小於k。
再轉化,能容納的總刀數 - 切出來小道後小道內不能切的刀數 < k 即爲不合法。
發現當n較大時,若是這個圖可以容納k刀,必定存在方案。
n比較小的時候就用公式計算。
1 #include <bits/stdc++.h> 2 3 typedef long long LL; 4 const int N = 100010; 5 6 LL n, k; 7 8 inline bool check(LL n, LL k) { 9 if(!n) { 10 return k == 0; 11 } 12 k = 3 * k + 1; 13 LL a = 1; 14 for(int i = 1; i <= n; i++) { 15 a *= 4; 16 if(a >= k) { 17 return 1; 18 } 19 } 20 return 0; 21 } 22 23 inline LL qpow(LL a, LL b) { 24 LL ans = 1; 25 while(b) { 26 if(b & 1) { 27 ans *= a; 28 } 29 a *= a; 30 b = b >> 1; 31 } 32 return ans; 33 } 34 35 inline void solve() { 36 37 scanf("%lld%lld", &n, &k); 38 39 if(!check(n, k)) { 40 printf("NO\n"); 41 return; 42 } 43 44 LL t = 0; 45 while((1ll << (t + 2)) - (t + 3) <= k && t < n) { 46 t++; 47 } 48 //k -= (1ll << (t + 2)) - (t + 3)); 49 LL x = n - t; 50 if(n <= 7) { 51 LL temp = (qpow(4, n) - 1) - (qpow(2, t + 1) - 1) * (qpow(4, x) - 1); 52 k *= 3; 53 if(k <= temp) { 54 printf("YES %d\n", x); 55 } 56 else { 57 printf("NO\n"); 58 } 59 return; 60 } 61 printf("YES %d\n", x); 62 return; 63 } 64 65 int main() { 66 67 int T; 68 scanf("%d", &T); 69 while(T--) { 70 solve(); 71 } 72 73 return 0; 74 }
看了看E,好神仙啊,徹底不知道如何操做......
給你個字母矩陣,問有多少個子矩陣知足:能夠只交換行內元素,使得這個子矩陣的每行每列都回文。n,m<=250
回來補票了。
先看一個合法的子矩陣有什麼性質。首先每行出現奇數次的元素不能超過1。而後對應行必須全部字母出現次數相同。
首先預處理出後一個限制。而後枚舉子矩陣的左右邊界,進行manacher。
1 #include <bits/stdc++.h> 2 3 typedef unsigned long long uLL; 4 typedef long long LL; 5 const int N = 252; 6 const uLL B = 13331; 7 8 uLL h[N * 2][N][N], pw[31]; 9 int n, m, bin[26], f[N * 2]; 10 char s[N * 2][N]; 11 std::bitset<N> valid[N * 2][N]; 12 13 int main() { 14 15 scanf("%d%d", &n, &m); 16 n = n * 2 - 1; 17 for(int i = 1; i <= n; i += 2) { 18 scanf("%s", s[i] + 1); 19 } 20 pw[0] = 1; 21 for(int i = 1; i <= 30; i++) { 22 pw[i] = pw[i - 1] * B; 23 } 24 25 /// prework 26 for(int i = 1; i <= n; i += 2) { 27 for(int l = 1; l <= m; l++) { 28 memset(bin, 0, sizeof(bin)); 29 int cnt = 0; 30 uLL H = 0; 31 for(int r = l; r <= m; r++) { 32 /// [l, r] add r 33 valid[i + 1][l][r] = 1; 34 if(i == 1) valid[i - 1][l][r] = 1; 35 int f = s[i][r] - 'a'; 36 bin[f]++; 37 //printf("%llu + %llu = ", H, pw[f]); 38 H += pw[f]; 39 //printf("%llu \n", H); 40 if(bin[f] & 1) { 41 cnt++; 42 } 43 else { 44 cnt--; 45 } 46 if(cnt <= 1) { 47 valid[i][l][r] = 1; 48 h[i][l][r] = H; 49 } 50 //printf("%d %d %d = %d %llu \n", i, l, r, (int)(valid[i][l][r]), h[i][l][r]); 51 } 52 } 53 } 54 55 LL ans = 0; 56 for(int l = 1; l <= m; l++) { 57 for(int r = l; r <= m; r++) { 58 /// [l, r] 59 int large = 0, pos = 0; 60 //printf("> > [%d %d] \n", l, r); 61 for(int i = 0; i <= n + 1; i++) { 62 if(!valid[i][l][r]) { 63 f[i] = 0; 64 pos = 0; 65 large = 0; 66 continue; 67 } 68 if(i > large) { 69 f[i] = 0; 70 int j = 1; 71 while(i - j >= 0 && i + j <= n + 1 && h[i - j][l][r] == h[i + j][l][r] && valid[i - j][l][r] && valid[i + j][l][r]) { 72 f[i] = j; 73 j++; 74 } 75 pos = i; 76 large = i + f[i]; 77 } 78 else { 79 f[i] = f[2 * pos - i]; 80 if(i + f[i] > large) { 81 f[i] = large - i; 82 } 83 int j = f[i] + 1; 84 while(i - j >= 0 && i + j <= n + 1 && h[i - j][l][r] == h[i + j][l][r] && valid[i - j][l][r] && valid[i + j][l][r]) { 85 f[i] = j; 86 j++; 87 } 88 if(i + f[i] > large) { 89 large = i + f[i]; 90 pos = i; 91 } 92 } 93 ans += (f[i] + 1) / 2; 94 //printf("f %d = %d ans += %d \n", i, f[i], (f[i] + 1) / 2); 95 } 96 } 97 } 98 99 printf("%lld\n", ans); 100 return 0; 101 }