Kickstart Round G 2018

第一次打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


*/
posted @ 2018-10-22 22:16  basasuya  阅读(392)  评论(0编辑  收藏  举报