Kickstart Round G 2018
阿新 • • 發佈:2018-12-16
第一次打codejam....慘的一比,才A1.5題,感覺自己最近狀態渣到姥姥家了,趕緊練練 A 模擬,注意0的問題
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <algorithm> #include <functional> #include <assert.h> #include <iomanip> using namespace std; const int N = 7005; const int M = 2e5 + 5; const int INF = 0x3f3f3f3f; const int MOD = 1000000007; typedef long long ll; int n; int A[N]; vector<int> vc[M]; int maxx; int solve(ll x, int pos) { if(x > maxx) return 0; int tt = (lower_bound(vc[x].begin(), vc[x].end(), pos) - vc[x].begin()); return vc[x].size() - tt; } int main() { freopen("A-large.in", "r", stdin); freopen("A-large.out", "w", stdout); // vector<int> t1; // t1.push_back(1); t1.push_back(2); // int tt = (lower_bound(t1.begin(), t1.end(), -1) - t1.begin()); // printf("%d\n", tt); int T; scanf("%d", &T); for(int _ = 1; _ <= T; ++_){ for(int i = 0; i < M; ++i) vc[i].clear(); scanf("%d", &n); maxx = -1; for(int i = 1; i <= n; ++i) { scanf("%d", &A[i]); vc[A[i]].push_back(i); maxx = max(maxx, A[i]); } ll ans = 0; for(int i = 1; i <= n; ++i) { for(int j = i + 1; j <= n; ++j) { if(A[i] == 0 && A[j] == 0) ans += n - j; else if(A[i] == 0 || A[j] == 0) ans += solve(0, j + 1); else { int pre = -1; if(A[i] % A[j] == 0) ans += solve(A[i] / A[j], j+1), pre = A[i] / A[j]; if(A[j] % A[i] == 0 && pre != A[j] / A[i]) ans += solve(A[j] / A[i], j+1), pre = A[j] / A[i]; if(pre != 1ll * A[j] * A[i]) ans += solve(1ll * A[j] * A[i], j+1); } } } printf("Case #%d: %lld\n", _, ans); } return 0; }
B 字首和,二分
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <algorithm> #include <functional> #include <assert.h> #include <iomanip> using namespace std; const int N = 4e5 + 5; const int MM = 1e5 + 5; // const int M = 2e5 + 5; const int INF = 0x3f3f3f3f; const int MOD = 1000000007; typedef long long ll; struct Node{ int num, offset; Node(int a=0, int b=0):num(a), offset(b) {} bool operator < (const Node &T) const { if(num != T.num) return num < T.num; else return offset < T.offset; /// } }; struct Tode{ ll sum; int val; int len; int now; Tode(ll a=0, int b=0, int c=0, int d=0):sum(a), val(b), len(c), now(d){} bool operator < (const Tode &T) const { if(sum != T.sum) return sum < T.sum; else return 1; /// } }; int n, q; ll X[N], Y[N], A[5], B[5], C[5], M[5]; ll Z[MM]; Node seq[N * 2]; Tode prefix[N * 2]; ll hhh[N * 2]; int main() { freopen("B-small-attempt4.in", "r", stdin); freopen("B-small-attempt4.out", "w", stdout); int T; scanf("%d", &T); for(int _ = 1; _ <= T; ++_){ scanf("%d %d", &n, &q); scanf("%lld %lld %lld %lld %lld %lld", &X[1], &X[2], &A[1], &B[1], &C[1], &M[1]); scanf("%lld %lld %lld %lld %lld %lld", &Y[1], &Y[2], &A[2], &B[2], &C[2], &M[2]); scanf("%lld %lld %lld %lld %lld %lld", &Z[1], &Z[2], &A[3], &B[3], &C[3], &M[3]); for(int i = 3; i <= n; ++i) { X[i] = (A[1] * X[i - 1] + B[1] * X[i - 2] + C[1]) % M[1]; Y[i] = (A[2] * Y[i - 1] + B[2] * Y[i - 2] + C[2]) % M[2]; } for(int i = 3; i <= q; ++i) { Z[i] = (A[3] * Z[i - 1] + B[3] * Z[i - 2] + C[3]) % M[3]; } for(int i = 1; i <= n; ++i) { X[i] ++; Y[i] ++; } for(int i = 1; i <= q; ++i) Z[i] ++; int tot = 0; ll tt = 0; for(int i = 1; i <= n; ++i) { if(X[i] > Y[i]) swap(X[i], Y[i]); // printf("%lld %lld\n", X[i], Y[i]); tt += Y[i] - X[i] + 1; seq[tot ++ ] = Node(X[i], 1); seq[tot ++ ] = Node(Y[i] + 1, -1); } // printf("%lld\n", tt); sort(seq, seq + tot); // for(int i = 0; i < tot; ++i) printf("%d %d : ", seq[i].num, seq[i].offset); printf("\n"); // seq[tot] = Node(seq[tot - 1].num + 1, 0); int tmp = 0; int tot2 = 0; ll all = 0; for(int i = 1; i < tot; ++i) { tmp += seq[i-1].offset; if(seq[i].num != seq[i-1].num) { int tt = seq[i].num - seq[i - 1].num; prefix[tot2] = Tode(all, tmp, tt, seq[i-1].num); // if(seq[i-1].num < 0) printf("hhh"); hhh[tot2 ++] = all; // printf("%lld %d %d from %d to %d\n", all, tmp, tt, seq[i-1].num, seq[i].num); all += 1ll * tt * tmp; } } // printf("%lld\n", all); ll ans = 0; for(int i = 1; i <= q; ++i) { // printf("hhh: %lld\n", Z[i]); Z[i] = tt - Z[i] + 1; if(Z[i] <= 0) continue; // Z[i] = 1; // printf("hhh: %lld\n", Z[i]); int pos = lower_bound(hhh, hhh + tot2, Z[i]) - hhh; pos --; ll lef = Z[i] - prefix[pos].sum; // printf("%d %d %lld\n", pos, prefix[pos].now, lef); ll tt = prefix[pos].now + lef / prefix[pos].val ; if(lef && (lef % prefix[pos].val == 0) ) tt --; // printf("%lld\n", tt); ans += 1ll * tt * i; } printf("Case #%d: %lld\n", _, ans); } return 0; } /* 3 5 5 3 1 4 1 5 9 2 7 1 8 2 9 4 8 15 16 23 42 3 5 1 3 1 4 1 5 9 2 7 1 8 2 9 4 8 15 16 23 42 5 5 3 1 4 1 5 9 2 7 1 8 2 9 4 8 15 16 23 42 1 2 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 2 100 1 2 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 2 100 55769 1 0 0 0 0 0 1000000000 999999999 999999999 0 0 999999999 1000000000 2512670 116262940 14464944 27962747 49835299 118572793 400000 1 97295458 97277314 13871606 251023440 11331260 274678035 97295458 97277314 13871606 251023440 11331260 274678035 244442 258459 136705 290087 276595 400000 */
C 狀壓dp+dfs
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <tuple> #include <bitset> #include <algorithm> #include <functional> #include <assert.h> #include <iomanip> using namespace std; const int N = 32768; const int M = 2e5 + 5; const int INF = 0x3f3f3f3f; const int MOD = 1000000007; typedef long long ll; int n, m, e, sx, sy, tx, ty; int mp[105][105]; int has[105][105]; int dir[][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} }; ll energy[N]; int exiting[N]; int remain[N]; int tag[105][105]; vector<tuple<int, int, int> > trap; int trapNum; ll dp[N]; void solve(ll all, int id) { memset(has, 0, sizeof(has)); queue<tuple<int, int> > Q; Q.push(make_tuple(sx, sy)); has[sx][sy] = 1; int flag = 0; int remainNum = 0; while(!Q.empty()) { int x = get<0>(Q.front()); int y = get<1>(Q.front()); Q.pop(); if(x == tx && y == ty) { flag = 1; } for(int i = 0; i < 4; ++i) { int dx = x + dir[i][0]; int dy = y + dir[i][1]; if(dx < 1 || dx > n || dy < 1 || dy > m || has[dx][dy] || mp[dx][dy] == -100000) continue; if(mp[dx][dy] < 0 ) { remainNum |= 1 << tag[dx][dy]; continue; } all += mp[dx][dy]; has[dx][dy] = 1; Q.push(make_tuple(dx, dy)); } } energy[id] = all; exiting[id] = flag; remain[id] = remainNum; } ll dfs(int mask) { if(~dp[mask]) return dp[mask]; ll ans = -1; if(exiting[mask] == 1) ans = energy[mask]; for(int i = 0; i < trapNum; ++i) { if( (remain[mask] >> i) & 1) { if(-mp[get<0>(trap[i])][get<1>(trap[i])] <= energy[mask]) ans = max(ans, dfs(mask | (1<<i))); } } dp[mask] = ans; return ans; } int main() { freopen("./C-large-practice2.in", "r", stdin); // freopen("./C-large-practice2.out", "w", stdout); int T; scanf("%d", &T); for(int _ = 1; _ <= T; ++_){ trap.clear(); memset(dp, -1, sizeof(dp)); scanf("%d %d %d %d %d %d %d", &n, &m, &e, &sx, &sy, &tx, &ty); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { scanf("%d", &mp[i][j]); } } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { if(mp[i][j] < 0 && mp[i][j] != -100000) { trap.emplace_back(i, j, mp[i][j]); tag[i][j] = trap.size() - 1; } } } trapNum = trap.size(); for(int i = 0; i < 1 << trapNum; ++i) { ll all = e; for(int j = 0; j < trapNum; ++j) { if( (i >> j) & 1 ) { mp[get<0>(trap[j])][get<1>(trap[j])] = 0; all += get<2>(trap[j]); } } solve(all, i); for(int j = 0; j < trapNum; ++j) { if( (i >> j) & 1 ) { mp[get<0>(trap[j])][get<1>(trap[j])] = get<2>(trap[j]); } } } // for(int i = 0; i < 1<<trapNum; ++i) printf("%lld %d %d\n", energy[i], remain[i], exiting[i]); printf("Case #%d: %lld\n", _, dfs(0)); } return 0; } /* 2 4 4 100 1 1 4 4 0 0 0 0 0 0 0 0 0 0 0 -100000 0 0 -100000 0 8 8 250 7 1 1 7 -100000 -100000 -100000 -100000 -100000 -100000 0 -100000 -100000 0 -100000 0 -400 0 0 -100000 -100000 100 -300 0 -100000 -300 -100000 -100000 -100000 0 -100000 500 -100000 250 0 -100000 -100000 -200 -100000 -100000 -100000 -100000 -100 -100000 -100000 0 -100000 0 0 50 50 -100000 0 0 -100 0 -100000 50 -100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 */