这次比赛是原题大战吗
A
顺序枚举没道题目,判断是切掉还是跳过,一直到结束为止,统计出两人分别切了多少题。
时间复杂度
#include <algorithm> #include <cctype> #include <cmath> #include <complex> #include <cstdio> #include <cstring> #include <deque> #include <functional> #include <list> #include <map> #include <iomanip> #include <iostream> #include <queue> #include <set> #include <stack> #include <string> #include <vector> using namespace std; #define int long long #define I inline #define ri register int #define For(i , x , y) for(ri i = x ; i <= y ; ++ i) #define Next(i , x) for(ri i = head[x] ; i ; i = e[i].nxt) I int read() { int s = 0 , w = 1; char ch = getchar(); while(ch < 48 || ch > 57) {if(ch == '-') w = -1; ch = getchar();} while(ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48) , ch = getchar(); return s * w; } const int N = 1e6 + 5; int n , T , m1 , m2 , a[N] , b[N]; signed main() { n = read() , T = read(); int T1 = T , T2 = T; m1 = read() , m2 = read(); For(i , 1 , n) a[i]= read(); For(i , 1 , n) b[i] = read(); int ans1 = 0 , ans2 = 0; For(i , 1 , n) { if(T1 < a[i] || b[i] >= m1) continue; ++ ans1 , T1 -= a[i]; } For(i , 1 , n) { if(b[i] >= m2) { if(T2 < a[i] * 2) continue; ++ ans2 , T2 -= a[i] * 2; } else { if(T2 < a[i]) continue; ++ ans2 , T2 -= a[i]; } } printf("%d %d\n" , ans1 , ans2); return 0; }
B
不难发现因为每个点所连的边所以是不可能出现答案为-1的情况的。
接下来只要对这张图黑白染色,因为必定存在合法方案,所以遇到一个点不合法的时候直接更改他的颜色即可。
时间复杂度
#include<bits/stdc++.h> using namespace std; #define ll long long #define ri register int #define For( i , x , y) for(ri i = x ; i <= y; ++ i) #define lc(x) x << 1 #define rc(x) x << 1 | 1 inline ll read() { ll s = 0 , w = 1; char ch = getchar(); while(ch < 48 || ch > 57) {if(ch == '-') w = -1; ch = getchar();} while(ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48) , ch = getchar(); return s * w; } const int N = 1e6 + 5; int n , tot , head[N] , m , col[N] , used[N]; struct Edge { int to , nxt; } e[N << 1]; inline void addedge(int x , int y) { e[++ tot] = (Edge) {y , head[x]} , head[x] = tot ; } inline void dfs(int u) { int cnt = 0; for(ri i = head[u] ; i ; i = e[i].nxt) { int v = e[i].to; if(!used[v]) { used[v] = 1 ; col[v] = col[u] ^ 1; dfs(v); } if(col[v] == col[u]) ++ cnt; } if(cnt > 1) col[u] = col[u] ^ 1; } int main() { n = read() , m = read(); For(i , 1 , m) { int u = read() , v = read(); addedge(u , v) , addedge(v , u); } For(i , 1 , n) if(!used[i]) dfs(i); For(i , 1 , n) printf("%d ", col[i] + 1) ; putchar('\n'); return 0; }
C
区间异或、区间求和。
直接用懒标记修改肯定是不行的。
考虑开20颗线段树分别记录每一个数的每一位,对每颗线段树进行修改和询问即可
时间复杂度
#include<bits/stdc++.h> using namespace std; #define ll long long #define ri register int #define For(i , x , y) for(i = x ; i <= y; ++ i) #define lc(x) x << 1 #define rc(x) x << 1 | 1 const int N = 2e5 + 5; inline ll read() { ll s = 0 , w = 1; char ch = getchar(); while(ch < 48 || ch > 57) {if(ch == '-') w = -1; ch = getchar();} while(ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48) , ch = getchar(); return s * w; } ll n , T , a[N] , bit[N << 2][21] , lazy[N << 1]; inline void pushup(ll x) { for(ri i = 20 ; ~i ; -- i) bit[x][i] = bit[lc(x)][i] + bit[rc(x)][i]; } inline void pushdown(ll x , ll l , ll r) { if(!lazy[x]) return ; lazy[lc(x)] ^= lazy[x]; lazy[rc(x)] ^= lazy[x]; int mid = (l + r) >> 1; for(ri i = 20 ; ~i ; -- i) if((lazy[x] >> i) & 1) { bit[lc(x)][i] = mid - l + 1 - bit[lc(x)][i]; bit[rc(x)][i] = r - mid - bit[rc(x)][i]; } lazy[x] = 0; } inline void build(ll rt , ll l , ll r) { if(l == r) { ll x = read(); for(ri i = 20 ; ~i ; -- i) if((x >> i) & 1) bit[rt][i] = 1; return; } int mid = (l + r) >> 1; build(lc(rt) , l , mid); build(rc(rt) , mid + 1 , r); pushup(rt); } inline void update(ll rt , ll l , ll r , ll L , ll R , ll k) { if(l == L && r == R ) { lazy[rt] ^= k; for(ri i = 20 ; ~i ; -- i) if((k >> i) & 1) bit[rt][i] = R - L + 1 - bit[rt][i]; return ; } pushdown(rt , L , R); int mid = (L + R) >> 1; if(r <= mid) update(lc(rt) , l , r , L , mid , k); else if(l > mid) update(rc(rt) , l , r , mid + 1 , R , k); else update(lc(rt) , l , mid ,L , mid , k) , update(rc(rt) , mid + 1 , r , mid + 1 , R , k); pushup(rt); } inline ll query(ll rt , ll l , ll r , ll L , ll R ) { if(l == L && r == R) { ll res = 0; for(ri i = 20 ; ~i ; -- i) res += (1 << i) * bit[rt][i]; return res; } pushdown(rt , L , R); int mid = (L + R) >> 1; if(r <= mid) return query(lc(rt) , l , r , L , mid ); else if(l > mid) return query(rc(rt) , l , r , mid + 1 , R); else return query(lc(rt) , l , mid ,L , mid ) + query(rc(rt) , mid + 1 , r , mid + 1 , R); } int main() { ri i , j; n = read(); T = read(); build(1 , 1 , n); while(T --) { int opt = read() , x = read() , y = read() , z; if(opt == 1) printf("%lld\n",query(1 , x , y , 1 , n)); else z = read() , update(1 , x , y , 1 , n , z); } return 0; }
D
这是个很妙的思维题。
我们发现每次修改过程中左上角的位置是一定会被修改的
总共有三个人,三种颜***r>所以最后只要看左上角的颜色就行了
#include<bits/stdc++.h> using namespace std; #define ll long long #define ri register int #define For( i , x , y) for(ri i = x ; i <= y; ++ i) #define lc(x) x << 1 #define rc(x) x << 1 | 1 inline ll read() { ll s = 0 , w = 1; char ch = getchar(); while(ch < 48 || ch > 57) {if(ch == '-') w = -1; ch = getchar();} while(ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48) , ch = getchar(); return s * w; } const int N = 1e3 +5; int T , n , m; char s[N][N]; int main() { T = read(); while(T --) { n = read() , m = read(); For(i , 1 , n) scanf("%s" , s[i] + 1); if(s[1][1] == 'R') puts("dreagonm"); else if(s[1][1] == 'G') puts("fengxunling"); else puts("BLUESKY007"); } return 0; }
E
签到题,不赘述