T1:
链接:https://www.luogu.org/problem/T92563
$sol1$:把所有的加起来,减去个数恒为$2$的,再减去$2 \times (n-1)$,即为答案。使用快速幂处理,还要注意答案可能出现负数。
$sol2$:推出矩阵式子后用矩阵快速幂来维护。
代码$(sol1)$:
#includeconst int mod = 19260817; typedef long long ll; using namespace std; ll n; ll qpow(ll x, ll y) { ll ans = 1; while(y) { if(y & 1) ans = (ll)(ans % mod * x % mod) % mod; x = (ll)(x % mod * x % mod) % mod; y >>= 1; } return ans % mod; } int main() { cin >> n; cout << ((qpow(2, n) - (2 * n)) % mod + mod) % mod << endl; return 0; }
T2:
链接:https://www.luogu.org/problem/T92564
$sol1$:使用一维差分,然后执行$y2-y1$次。
$sol2$:直接二维差分,用前缀和维护。
代码$(sol1)$:
#includeconst int MAXN = 1050; using namespace std; int n, m, x, y, xx, yy, a[MAXN][MAXN], f[MAXN][MAXN]; int read() { int x = 0; bool sign = false; char alpha = 0; while(!isdigit(alpha)) { sign |= alpha == '-'; alpha = getchar(); } while(isdigit(alpha)) { x = (x << 1) + (x << 3) + (alpha ^ 48); alpha = getchar(); } return sign ? -x : x; } int main() { n = read(); m = read(); while(m--) { x = read(); y = read(); xx = read(); yy = read(); for(int i = y; i <= yy; i++) { a[xx + 1][i] --; a[x][i] ++; } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { a[i][j] = a[i - 1][j] + a[i][j]; cout << a[i][j] << " "; } cout << endl; } return 0; }
T3:
链接:https://www.luogu.org/problem/T92569
$sol1:$:由于$k$的数据范围很小,考虑枚举出$2^k$的所有情况。有个优化即为把与输入重复的去除。先异或,然后用$lowbit$数出不同的个数,统计即可。
题目中最坏情况如何统计?即先取最小值后取最大值。
$sol2$:多源最短路,$bfs$即可。
代码$(sol1)$:
#includeconst int INF = 1 << 30; const int MAXN = 200050; using namespace std; int n, k, o, cnt, ans, num, cnt1, Min = INF, b[MAXN], c[MAXN]; bool vis[MAXN]; string s[MAXN]; char e; int lowbit(int x) { return x & (-x); } int main() { ios::sync_with_stdio(false); cin >> n >> k; for(int i = 1; i <= n; i++) { int p = 0; for(int j = k - 1; j >= 0; j--) { cin >> e; o = e - '0'; p |= (o << j); } if(!vis[p]) { b[++cnt1] = p; vis[p] = true; } } for(int i = 0; i < (1 << k); i++) { if(!vis[i]) c[++cnt] = i; } if(cnt == 0) { cout << "0" << endl; return 0; } for(int i = 1; i <= cnt; i++) { for(int j = 1; j <= cnt1; j++) { int res = b[j] ^ c[i]; while(res > 0) { res -= lowbit(res); num++; } Min = min(Min, num); num = 0; } ans = max(ans, Min); Min = INF; } cout << ans << endl; return 0; }
T4:
链接:https://www.luogu.org/problem/T92570
$sol$:直接暴力$bfs$加上个剪枝优化就行了。
代码:
#include#include #include #include #include #include const int INF = 1 << 30; const int MAXN = 1050; const int dirx[] = {1, 0, 0, -1}; const int diry[] = {0, 1, -1, 0}; using namespace std; struct node { int x, y, t; }; queue q; struct node1{ int x, y; }p[MAXN << 1]; int t, n, x, y, tmax = INF; bool vis[MAXN][MAXN]; int read (){ int xx = 0; bool sign = false; char alpha = 0; while(!isdigit(alpha)) { sign |= alpha == '-'; alpha = getchar(); } while(isdigit(alpha)) { xx = (xx << 1) +(xx << 3) + (alpha ^48); alpha = getchar(); } return sign ? -xx : xx; } bool check(int x, int y) { return x < 1 || x > n || y < 1 || y > n; } bool bfs() { int nowt = 0; q.push((node){1, 1, 0}); vis[1][1] = true; while(!q.empty()) { node now = q.front(); q.pop(); int x = now.x, y = now.y, t = now.t; if(t != nowt) { vis[p[t].x][p[t].y] = true; nowt = t; } if(x == n && y == n) return true; else if(vis[n][n] && t == tmax) return false; for(int i = 0; i < 4; i++) { int dx = x + dirx[i], dy = y + diry[i]; if(check(dx, dy) || vis[dx][dy] || (dx == p[t + 1].x && dy == p[t + 1].y && (dx != n && dy != n))) continue; vis[dx][dy] = true; q.push((node){dx, dy, t + 1}); } } return false; } void init() { tmax = INF; while(!q.empty()) q.pop(); for(int i = 1; i <= n; i++) { p[i].x = p[i].y = 0; for(int j = 1; j <= n; j++) vis[i][j] = false; } } int main() { t = read(); while(t--) { n = read(); for(int i = 1; i <= (n << 1) - 2; i++) { x = read(); y = read(); if(x == n && y == n && tmax == INF) tmax = i; p[i].x = x; p[i].y = y; } bfs() ? printf("Yes\n") : printf("No\n"); init(); } return 0; }