2018暑假多校(杭電 + 牛客)

天坑。。。php

杭電html

dls代碼:https://ideone.com/Wo55gijava

官方題解:http://bestcoder.hdu.edu.cn/blog/node

2018 Multi-University Training Contest 1ios

1001 Maximum Multiplec++

打表找規律,發現只有當n是3倍數或者4倍數時纔有解git

並且當n%3 == 0,max(x*y*z) = (n/3) * (n/3) * (n/3)  = n^3 / 27,數組

當n%4 == 0, max(x*y*z) = (n/2) * (n/4) * (n/4) = n^3 / 32。app

正解是解不定方程組less

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

int main() {
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        if(n % 3 == 0) printf("%lld\n", 1LL * n * n * n / 27);
        else if(n % 4 == 0)printf("%lld\n", 1LL * n * n * n / 32);
        else printf("-1\n");
    }
    return 0;
}
View Code

1002 Balanced Sequence

思路:貪心,先把每一個括號序列用棧來使得中間的都括號都匹配,使得右括號都在左邊,左括號都在右邊

而後排序,咱們先把右括號小於等於左括號的排在前面,而後對於右括號小於等於左括號的狀況,咱們按

右括號從小到大排序(由於最左邊的右括號都是被浪費掉的,浪費的越小越好),而後把右括號大於左括

號的狀況排在後面,對於後面這種狀況,咱們按左括號從大到小排序(由於最右邊的左括號都是被浪費掉

的,浪費的越小越好)。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
struct node {
    int l, r;
    bool operator < (const node &t) const {
        if(r <= l && t.r > t.l) return true;
        if(r > l && t.r <= t.l) return false;
        if(r <= l && t.r <= t.l) return r < t.r;
        if(r > l && t.r > t.l) return l > t.l;
    }
}a[N];
char s[N];
int main() {
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        int ans = 0;
        for (int i = 0; i < n; i++) {
            scanf("%s", s);
            int l = 0, r = 0;
            for (int j = 0; j < strlen(s); j++) {
                if(s[j] == '(') l++;
                else {
                    if(l) l--, ans += 2;
                    else r++;
                }
            }
            a[i].l = l;
            a[i].r = r;
        }
        sort(a, a+n);
        int now = a[0].l;
        for (int i = 1; i < n; i++) {
            if(a[i].r >= now) {
                ans += now*2;
                now = 0;
            }
            else {
                ans += a[i].r*2;
                now -= a[i].r;
            }
            now += a[i].l;
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

1003 Triangle Partition

1004 Distinct Values

1005 Maximum Weighted Matching

1006 Period Sequence

1007 Chiaki Sequence Revisited

思路:打表找規律,發現每一個數i出現了lowbit(i)的長度次,而後二分最後a[n]的值,複雜度nlog(n)*log(n),會TLE,而後發現,a[n] -> n/2,因此將二分區間改成[n/2, n/2+100]下降複雜度

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int MOD = 1e9 + 7;
const int inv = 5e8 + 4;
LL cal(LL m) {
    LL ans = 0;
    for (int i = 0; i <= 60; i++) {
        LL cnt = m / (1LL << i);
        if(cnt == 0) break;
        ans += cnt;
    }
    return ans;
}
LL sum(LL m) {
    LL ans = 0;
    for (int i = 0; i <= 60; i++) {
        LL tot = 1LL << i;
        LL cnt = m / tot;
        if(cnt == 0) break;
        LL t = ((cnt % MOD * ((cnt + 1) % MOD)) % MOD * inv) % MOD;
        t = (t * (tot % MOD) % MOD) % MOD;
        ans = (ans + t) % MOD;
    }
    return ans;
}
int main() {
    int T;
    LL n;
    scanf("%d", &T);
    while(T--) {
        scanf("%lld", &n);
        if(n <= 2) {
            printf("%lld\n", n);
            continue;
        }
        n--;
        LL l = n/2, r = (n/2)+100, m = (l + r) >> 1;
        while(l < r) {
            if(cal(m) >= n) r = m;
            else l = m + 1;
            m = (l + r) >> 1;
        }
        LL tot = cal(m-1);
        LL res = n - tot;
        LL ans = (res % MOD * (m % MOD)) % MOD;
        ans = (ans + sum(m-1) + 1) % MOD;
        ans = (ans + MOD) % MOD;
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

1008 RMQ Similar Sequence

1009 Lyndon Substring

1010 Turn Off The Light

1011 Time Zone

2018 Multi-University Training Contest 2

1001 Absolute

1002 Counting Permutations

1003 Cover

思路:將度數爲奇數的點兩兩相連,而後跑歐拉圖

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
vector<pii>g[N];
bool nodevs[N], edgevs[2*N];
int deg[N], cnt = 0, t, st;
vector<int>vc, vcc;
vector<int>ans[N];
void dfs(int u) {
    nodevs[u] = true;
    if(deg[u]&1) vc.pb(u), st = u;
    cnt++;
    for (int i = 0; i < g[u].size(); i++) {
        if(!nodevs[g[u][i].fi]) {
            dfs(g[u][i].fi);
        }
    }
}
void add() {
    for (int i = 0; i < vc.size(); i += 2) {
        g[vc[i]].pb({vc[i+1], t});
        g[vc[i+1]].pb({vc[i], t});
        t++;
    }
}

void DFS(int u) {
    for (int i = 0; i < g[u].size(); i++) {
        if(!edgevs[abs(g[u][i].se)]) {
            edgevs[abs(g[u][i].se)] = true;
            DFS(g[u][i].fi);
            vcc.pb(g[u][i].se);
        }
    }
}
void debug() {
    for (int i = 0; i < vcc.size(); i++) cout << vcc[i] << " ";
    cout << endl;
}
int main() {
    int n, m, u, v;
    while(~scanf("%d%d", &n, &m)) {
        mem(nodevs, false);
        mem(edgevs, false);
        mem(deg, 0);
        for (int i = 0; i <= n; i++) g[i].clear();
        for (int i = 1; i <= m; i++) {
            ans[i].clear();
            scanf("%d%d", &u, &v);
            g[u].pb({v, -i});
            g[v].pb({u, i});
            deg[u]++;
            deg[v]++;
        }
        int tot = 0;
        t = m+1;
        for (int i = 1; i <= n; i++) {
            if(!nodevs[i]) {
                cnt = 0;
                st = i;
                vc.clear();
                dfs(i);
                if(cnt == 1) continue;
                add();

                vcc.clear();
                DFS(st);
                //debug();
                int s = 0, sz = vcc.size();
                if(vc.size() > 1) {
                    while(abs(vcc[s]) <= m) {
                        s++;
                    }
                }
                else tot++;
                for (int i = s; i < s+sz; i++) {
                    if(abs(vcc[i%sz]) > m) tot++;
                    else ans[tot].pb(vcc[i%sz]);
                }

            }
        }
        printf("%d\n", tot);
        for (int i = 1; i <= tot; i++) {
            printf("%d ", ans[i].size());
            for (int j = 0; j < ans[i].size(); j++) printf("%d%c", ans[i][j], " \n"[j==ans[i].size()-1]);
        }
    }
    return 0;
}
View Code

1004 Game

思路:考慮將遊戲變成初始時只有2~n,若是先手必勝的話,那麼先手第一步按這樣取就獲勝了;若是後手必勝的話,那麼先手第一步取走1就獲勝了。

因此不管前後手Alice必勝。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

int main() {
    int n;
    while(cin >> n) puts("Yes");
    return 0;
}
View Code

1005 Hack It

思路:數論構造

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 3e3 + 100;
int a[N][N], p = 47;
int main() {
    fio;
    cout << 2000 << endl;
    for (int i = 0; i < p; i++) {
        for (int j = 0; j < p; j++) {
            for (int k = 0; k < p; k++) {
                a[i*p+j][k*p+(i+k*j)%p] = 1;
            }
        }
    }
    for (int i = 0; i < 2000; i++) {
        for (int j = 0; j < 2000; j++)
            printf("%d", a[i][j]);
        printf("\n");
    }
    return 0;
}
View Code

1006 Matrix

1007 Naive Operations

思路:考慮只有當ai 爲 bi 倍數時i這個位置才須要被更新,因而咱們倒着減bi,當bi被減成0是,咱們在i這個位置+1,從新將bi設爲原來的bi

判斷bi爲不爲0用線段樹維護,答案用樹狀數組維護,複雜爲nlog(n)^2,由於調和級數的和約爲n*ln(n),因此最多更新nlog(n)次

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
const int INF = 0x3f3f3f3f;
int b[N];
int mn[N*4], lazy[N*4], n;
LL bit[N];
vector<int>vc;
void add(int x) {
    while(x <= n) bit[x]++, x += x&-x;
}
LL sum(int x) {
    LL ans = 0;
    while(x) ans += bit[x], x -= x&-x;
    return ans;
}
void push_up(int rt) {
    mn[rt] = min(mn[rt<<1], mn[rt<<1|1]);
}
void push_down(int rt) {
    lazy[rt<<1] += lazy[rt];
    lazy[rt<<1|1] += lazy[rt];
    mn[rt<<1] += lazy[rt];
    mn[rt<<1|1] += lazy[rt];
    lazy[rt] = 0;
}
void build(int rt, int l, int r) {
    if(l == r) {
        lazy[rt] = 0;
        mn[rt] = b[l];
        return ;
    }
    lazy[rt] = 0;
    int m = (l + r) >> 1;
    build(ls);
    build(rs);
    push_up(rt);
}
void update(int L, int R, int rt, int l, int r, int d) {
    if(L <= l && r <= R) {
        mn[rt] += d;
        if(mn[rt] == 0) {
            if(l == r) {
                vc.pb(l);
            }
            else {
                if(lazy[rt]) push_down(rt);
                int m = (l + r) >> 1;
                update(L, R, ls, d);
                update(L, R, rs, d);
            }
        }
        else lazy[rt] += d;
        return ;
    }
    if(lazy[rt]) push_down(rt);
    int m = (l+r) >> 1;
    if(L <= m)update(L, R, ls, d);
    if(R > m) update(L, R, rs, d);
    push_up(rt);
}
int query(int L, int R, int rt, int l, int r) {
    if(L <= l && r <= R) return mn[rt];
    int ans = INF;
    int m = (l+r) >> 1;
    if(L <= m) ans = min(ans, query(L, R, ls));
    if(R > m) ans = min(ans, query(L, R, rs));
    return ans;
}
int main() {
    fio;
    string s;
    int q, l, r;
    while(cin >> n >> q) {
        for (int i = 1; i <= n; i++) cin >> b[i];
        for (int i = 0; i <= n; i++) bit[i] = 0;
        build(1, 1, n);
        for (int i = 1; i <= q; i++) {
            cin >> s >> l >> r;
            if(s == "add") {
                update(l, r, 1, 1, n, -1);
                if(vc.size() > 0) {
                    //cout << vc.size() << endl;
                    for (int j = 0; j < vc.size(); j++) {
                        add(vc[j]);
                        update(vc[j], vc[j], 1, 1, n, b[vc[j]]);
                    }
                    vc.clear();
                }
            }
            else {
                cout << sum(r) - sum(l-1) << endl;
            }
        }
    }
    return 0;
}
View Code

1008 Odd Shops

1009 Segment

1010 Swaps and Inversions

思路:求個逆序數,再乘以最小花費

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
vector<int>vc;
int a[N], bit[N], n;
void add(int x) {
    while(x <= n) bit[x] ++, x += x&-x;
}
int sum(int x) {
    int ans = 0;
    while(x) ans += bit[x], x -= x&-x;
    return ans;
}
int main() {
    int x, y;
    while(~ scanf("%d %d %d", &n, &x, &y)) {
        vc.clear();
        for (int i = 0; i <= n; i++) bit[i] = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            vc.pb(a[i]);
        }
        sort(vc.begin(), vc.end());
        vc.erase(unique(vc.begin(), vc.end()), vc.end());
        for (int i = 1; i <= n; i++) {
            a[i] = lower_bound(vc.begin(), vc.end(), a[i]) - vc.begin()  +1;
        }
        LL tot = 0, ans;
        for (int i = 1; i <= n; i++) {
            tot += i - 1 - sum(a[i]);
            add(a[i]);
        }
        ans = min(x, y) * tot;
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

2018 Multi-University Training Contest 3

1001 Problem A. Ascending Rating

思路:考慮到從前日後維護單調隊列,維護的是單調遞減的序列,與題目不符,因而咱們從後往前維護單調隊列,這樣單調遞減就變成單調遞增了

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e7 + 5;
int a[N], nxt[N], tot[N];
int MOD;
int main() {
    int T, n, m, k, p, q, r;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d%d%d%d%d%d", &n, &m, &k, &p, &q, &r, &MOD);
        for (int i = 1; i <= k; i++) scanf("%d", &a[i]);
        for (int i = k+1; i <= n; i++) a[i] = (1LL * p * a[i-1] + 1LL * q * i + r) % MOD;
        LL A = 0, B = 0;
        deque<int>q;
        for (int j = n; j >= 1; j--) {
            while(!q.empty() && a[q.back()] <= a[j]) q.pop_back();
            q.push_back(j);
            while(!q.empty() && q.front() > j + m - 1) q.pop_front();
            if(j <= n-m+1) {
                //cout << a[q.front()] << " " << q.size() << endl;
                A += a[q.front()] ^ j;
                B += ((int)q.size()) ^ j;
            }
        }
        printf("%lld %lld\n", A, B);
    }
    return 0;
}
View Code

1002 Problem B. Cut The String

1003 Problem C. Dynamic Graph Matching

思路:狀壓dp

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int MOD = 1e9 + 7;
char s[15];
int dp[2][1100][10];
int n, m;
int main() {
    int T, u, v;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &n, &m);
        int now = 0;
        mem(dp, 0);
        for (int i = 0; i < (1<<n); i++) dp[now][i][0] = 1;
        while(m--) {
            scanf("%s %d %d", s, &u, &v);
            now ^= 1;
            int flag;
            if(s[0] == '+') flag = 1;
            else flag = -1;
            int mx = 0;
            for (int i = 0; i < (1<<n); i++) {
                dp[now][i][0] = 1;
                for (int j = 1; j <= n/2; j++) {
                    if((i|(1<<u-1)|(1<<v-1)) == i)dp[now][i][j] = (dp[now^1][i][j] + flag * dp[now^1][i^(1<<u-1)^(1<<v-1)][j-1]) % MOD;
                    else dp[now][i][j] = dp[now^1][i][j];
                }
            }
            for (int i = 1; i <= n/2; i++) printf("%d%c", (dp[now][(1<<n)-1][i] + MOD) % MOD, " \n"[i==n/2]);
        }
    }
    return 0;
}
View Code

1004 Problem D. Euler Function

1005 Problem E. Find The Submatrix

1006 Problem F. Grab The Tree

1007 Problem G. Interstellar Travel

1008 Problem H. Monster Hunter

1009 Problem I. Random Sequence

1010 Problem J. Rectangle Radar Scanner

1011 Problem K. Transport Construction

1012 Problem L. Visual Cube

思路:構造

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
#pragma GCC optimize(2) #pragma GCC optimize(3) #p using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

char s[100][100];
int main() {
    int T, a, b, c;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d%d", &a, &b, &c);
        int n = (c+b) * 2 + 1;
        int m = (a+b) * 2 + 1;
        for (int i = 1; i <= n; i++) {
            if(i&1){
                for (int j = 1; j <= m; j++) {
                    if(j&1)s[i][j] = '+';
                    else s[i][j] = '-';
                }
            }
            else {
                for (int j = 1; j <= m; j++) {
                    s[i][j] = '.';
                }
            }
        }

        for (int i = 1; i <= 2*b; i++) {
            for (int j = 1; j <= 2*b - i + 1; j++) {
                s[i][j] = '.';
                s[n-i+1][m-j+1] = '.';
            }
        }

        for (int i = 2*b + 2; i <= n; i += 2) {
            for (int j = 1; j <= 2*a; j += 2) {
                s[i][j] = '|';
            }
        }
        int st = 2*b+2, ed = n;
        for (int i = 2*a + 1; i <= m; i += 2) {
            for (int j = st; j <= ed; j += 2) {
                s[j][i] = '|';
                s[j][i+1] = '/';
                s[j-1][i+1] = '.';
            }
            st -= 2;
            ed -= 2;
        }

        for (int i = 2; i <= 2*b; i += 2) {
            for (int j = 2*b - i + 2; j <= 2*b - i + 2 + 2*a; j += 2) {
                s[i][j] = '/';
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                putchar(s[i][j]);
            }
            puts("");
        }
    }
    return 0;
}
View Code

1013 Problem M. Walking Plan

2018 Multi-University Training Contest 4

1001 Problem A. Integers Exhibition

1002 Problem B. Harvest of Apples

思路:

咱們打表發現組合數的和 和 組合數的遞推 是同樣的:sum(n, m) = sum(n-1, m) + sum(n-1, m-1)

對N進行分塊,先預處理出每i*√N行的值,而後對於每一個sum(n, m)咱們都能在O(√N)時間之內遞推出它的值

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5, M = 350;
const int MOD = 1e9 + 7;
int blo = sqrt(N);
vector<int>c[M];
int C[M][M], inv[N], tot = 0;
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        if(k&1) ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
    }
    return ans;
}
void init() {
    int cnt = 1;
    inv[1] = 1;
    for (int i = 2; i < N; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD;
    for (int i = 1; i < N; i += blo) {
        c[cnt].resize(i+blo+5);
        c[cnt][0] = 1;
        LL t = 1;
        for (int j = 1; j <= i; j++) {
            tot++;
            t = (t * (i-j+1)) % MOD;
            t = (t * inv[j]) % MOD;
            c[cnt][j] = (c[cnt][j-1] + t) % MOD;
        }
        for (int j = i+1; j <= i+blo; j++) c[cnt][j] = c[cnt][i];
        cnt++;
    }
    C[0][0] = 1;
    for (int i = 1; i < M; i++) {
        for (int j = 1; j <= i; j++)
            C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
    }
}
int main() {
    init();
    int T, n, m;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &n, &m);
        int bl = (n-1)/blo;
        int base = bl*blo + 1;
        int dis = n - base + 1;
        int l = m - dis + 1, r = m;
        LL ans = 0;
        for (int i = l, j = 1; i <= r; i++, j++) {
            if(i < 0) continue;
            ans = (ans + 1LL*C[dis][j]*c[bl+1][i]%MOD) % MOD;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

1003 Problem C. Problems on a Tree

1004 Problem D. Nothing is Impossible

思路:

貪心

若是僅有 1 道題,至少有一我的作對這題須要有 錯誤答案個數 + 1 我的。

咱們將題目按錯誤答案個數從小到大排序,從錯誤答案個數小的開始回來,看最多回答了幾個問題後存在1我的全對

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 222;
pii a[N];
bool cmp(pii a, pii b) {
    return a.se < b.se;
}
int main() {
    int T, n, m;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++) {
            scanf("%d %d", &a[i].fi, &a[i].se);
        }
        sort(a, a+n, cmp);
        int ans = 0;
        for (int i = 0; i < n; i++) {
            if(m >= 1 + a[i].se) {
                m = floor((double)m  / (1 + a[i].se));
                if(m >= 1) ans++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

1005 Problem E. Matrix from Arrays

思路:咱們發現當n爲奇數時是以n*n爲循環,當n爲偶數時是以2n * 2n爲循環

因而咱們打好2n * 2n的表,算好前綴和,注意處理好邊界

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e3 + 5;
int M[N][N], A[N];
LL sum[N][N] = {0};
int main() {
    fio;
    int T;
    cin >> T;
    while(T--) {
        int cursor = 0,  n, q, x, y, x1, y1;
        cin >> n;
        for (int i = 0; i < n; i++) cin >> A[i];
        for (int i = 0; i < 10*n; ++i) {
            for (int j = 0; j <= i; ++j) {
                M[j+1][i - j+1] = A[cursor];
                cursor = (cursor + 1) % n;
            }
        }
        /*for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cout << M[i][j] << " ";
            }
            cout<< endl;
        }*/
        for (int i = 1; i <= 4*n; i++) {
            for (int j = 1; j <= 4*n; j++) {
                sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + M[i][j];
            }
        }
        cin >> q;
        while(q--) {
            cin >> x >> y >> x1 >> y1;
            x++, y++, x1++, y1++;
            int h = (x1 - x + 1);
            int w = (y1 - y + 1);
            LL ans = 0;
            ans = 1LL * (w/(2*n)) * (h/(2*n)) * sum[2*n][2*n];
            int w1 = w%(2*n);
            int h1 = h%(2*n);
            int xx = x%(2*n);
            int yy = y%(2*n);
            if(xx == 0) xx += 2*n;
            if(yy == 0) yy += 2*n;
            LL s1, s2, s3;
            if(w1) {
                int xxx = xx + 2*n - 1, yyy = yy + w1 - 1;
                s1 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1];
            }
            else s1 = 0;
            if(h1) {
                int xxx = xx + h1 - 1, yyy = yy + 2*n - 1;
                s2 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1];
            }
            else s2 = 0;
            if(w1 && h1) {
                int xxx = xx + h1 - 1, yyy = yy + w1 - 1;
                s3 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1];
            }
            else s3 = 0;
            ans += s1*(h/(2*n)) + s2 * (w/(2*n)) + s3;
            cout << ans << endl;
        }
    }
    return 0;
}
View Code

1006 Problem F. Travel Through Time

1007 Problem G. Depth-First Search

1008 Problem H. Eat Cards, Have Fun

1009 Problem I. Delightful Formulas

1010 Problem J. Let Sudoku Rotate

思路:搜索剪枝

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 100;
char s[N][N];
int g[N][N];
int t[N][N], ans;
bool vis[16];
void Rotate(int x, int y) {
    for (int i = 1, a = y; i <= 4; i++, a++) {
        for (int j = 1, b = x+3; j <= 4; j++, b--) {
            t[i][j] = g[b][a];
        }
    }
    for (int i = 1, a = x; i <= 4; i++, a++) {
        for (int j = 1, b = y; j <= 4; j++, b++) {
            g[a][b] = t[i][j];
        }
    }
}
bool check(int x, int y) {
    for (int i = 1; i <= x; i++) {
        mem(vis, false);
        for (int j = 1; j <= y; j++) {
            if(vis[g[i][j]]) return false;
            else vis[g[i][j]] = true;
        }
    }
    for (int j = 1; j <= y; j++) {
        mem(vis, false);
        for (int i = 1; i <= x; i++) {
            if(vis[g[i][j]]) return false;
            else vis[g[i][j]] = true;
        }
    }
    return true;
}
void dfs(int pos, int tot) {
    if(pos == 16) {
        ans = min(ans, tot);
        return ;
    }
    for (int i = 0; i < 4; i++) {
        if(check(pos/4*4+4, pos%4*4+4)) dfs(pos+1, tot+i);
        Rotate(pos/4*4+1, pos%4*4+1);
    }
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        for (int i = 1; i <= 16; i++) {
            scanf("%s", s[i]+1);
        }
        for (int i = 1; i <= 16; i++) {
            for (int j = 1; j <= 16; j++) {
                if(isdigit(s[i][j])) g[i][j] = s[i][j] - '0';
                else g[i][j] = s[i][j] - 'A' + 10;
            }
        }
        ans = 16*3;
        dfs(0, 0);
        printf("%d\n", ans);
    }
    return 0;
}
View Code

1011 Problem K. Expression in Memories

思路:模擬

隊友代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

bool check(char ch)
{
    if(ch=='+'||ch=='*') return true;
    return false;
}

int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        string s;
        cin>>s;
        int len=s.size();
        int ok=1;
        int flag=0;
        for(int i=0;i<len;i++)
        {
            if(i==0&&s[i]=='0'&&!check(s[i+1])&&i+1<len)
            {
                if(s[i+1]=='?') s[i+1]='+';
                else
                {
                    ok=0;
                    break;
                }
            }
            if(check(s[i])&&s[i+1]=='0'&&!check(s[i+2])&&i+2<len)
            {
                if(s[i+2]=='?') s[i+2]='+';
                else
                {
                    ok=0;
                    break;
                }
            }
            if(s[i]=='?') s[i]='5';
            else if(check(s[i])&&check(s[i+1]))
            {
                ok=0;
                break;
            }
        }
        if(check(s[0])||check(s[len-1])) ok=0;
        if(!ok) printf("IMPOSSIBLE\n");
        else cout<<s<<endl;
    }
}
View Code

1012 Problem L. Graph Theory Homework

思路:

容易證實floor(sqrt(a)) + floor(sqrt(b)) > floor(sqrt(a+b))

因此最短路就是從1走到n

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 2e5 + 5;
int a[N];
int main() {
    int n, T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        printf("%d\n", (int)sqrt(abs(a[1] - a[n])));
    }
    return 0;
}
View Code

2018 Multi-University Training Contest 5

1001 Always Online

1002 Beautiful Now

思路:暴力搜索

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

string s, a, b, ansmn, ansmx;
int n, k;
void dfs(int pos, int cnt) {
    if(cnt > k) return ;
    if(pos == n) {
        ansmn = min(ansmn, a);
        ansmx = max(ansmx, a);
        return ;
    }
    for (int i = pos; i < n; i++) {
        if(i == pos) {
            if(pos == 0 && a[i] == '0');
            else {
                dfs(pos+1, cnt);
            }
        }
        else {
            if(pos == 0 && a[i] == '0');
            else {
                swap(a[i], a[pos]);
                dfs(pos+1, cnt+1);
                swap(a[i], a[pos]);
            }
        }
    }
}
int main() {
    fio;
    int T;
    cin >> T;
    while(T--) {
        cin >> s >> k;
        n = s.size();
        if(k >= n-1) {
            sort(s.begin(), s.end());
            a = s;
            reverse(s.begin(), s.end());
            b = s;
            for (int i = 0; i < n; i++) {
                if(a[i] != '0') {
                    swap(a[0], a[i]);
                    break;
                }
            }
            cout << a << " " << b << endl;
        }
        else {
            a = s;
            ansmn = a;
            ansmx = a;
            dfs(0, 0);
            cout << ansmn << " " << ansmx << endl;
        }

    }
    return 0;
}
View Code

1003 Call It What You Want

1004 Daylight

1005 Everything Has Changed

思路:餘弦定理

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define pf emplace_front
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

int main() {
    int T, m;
    double R, x, y, r;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %lf", &m, &R);
        double ans = 2 * pi * R;
        while(m--) {
            scanf("%lf %lf %lf", &x, &y, &r);
            double dd = x*x + y*y;
            if(sqrt(dd) > R + r || sqrt(dd) < R - r) continue;
            double sub = acos((R*R + dd - r*r) / (2*R*sqrt(dd)));
            double pls = acos((r*r + dd - R*R) / (2*r*sqrt(dd)));
            ans -= 2*sub*R;
            ans += 2*pls*r;
        }
        printf("%.10f\n", ans);
    }
    return 0;
}
View Code

1006 Fireflies

1007 Glad You Came

思路:線段樹剪枝或者st表逆運用

線段樹(700ms)

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
const int MOD = 1 << 30;
int tree[N<<2], lazy[N<<2];
unsigned int X, Y, Z, t[5];
inline unsigned int f() {
    X ^= X << 11;
    X ^= X >> 4;
    X ^= X << 5;
    X ^= X >> 14;
    unsigned int W = X ^ (Y ^ Z);
    X = Y;
    Y = Z;
    Z = W;
    return Z;
}
inline void push_up(int rt) {
    tree[rt] = min(tree[rt<<1], tree[rt<<1|1]);
}
inline void push_down(int rt) {
    tree[rt<<1|1] = max(lazy[rt], tree[rt<<1|1]);
    tree[rt<<1] = max(lazy[rt], tree[rt<<1]);
    lazy[rt<<1|1] = max(lazy[rt], lazy[rt<<1|1]);
    lazy[rt<<1] = max(lazy[rt], lazy[rt<<1]);
    lazy[rt] = 0;
}
void build(int rt, int l, int r) {
    if(l == r) {
        tree[rt] = lazy[rt] = 0;
        return ;
    }
    lazy[rt] = tree[rt] = 0;
    int m = l+r >> 1;
    build(ls);
    build(rs);
}
inline void update(int L, int R, int v, int rt, int l, int r) {
    if(tree[rt] >= v)  return ;
    if(L <= l && r <= R) {
        if(tree[rt] >= v)  return ;
        else {
            if(l == r) tree[rt] = v, lazy[rt] = v;
            else {
                if(lazy[rt] < v) lazy[rt] = v;
            }
            return ;
        }
    }
    if(lazy[rt]) push_down(rt);
    int m = l+r >> 1;
    if(L <= m) update(L, R, v, ls);
    if(R > m) update(L, R, v, rs);
    push_up(rt);
}
inline int query(int p, int rt, int l, int r) {
    if(l == r) return tree[rt];
    if(lazy[rt]) push_down(rt);
    int m = l+r >> 1;
    if(p <= m) return query(p, ls);
    else return query(p, rs);
}
int main() {
    int T, n, m;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z);
        build(1, 1, n);
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= 3; j++) t[j] = f();
            int l = min(t[1]%n + 1, t[2]%n + 1);
            int r = max(t[1]%n + 1, t[2]%n + 1);
            int v = t[3] % MOD;
            update(l, r, v, 1, 1, n);
        }
        LL ans = 0;
        for (int i = 1; i <= n; i++) {
            int t = query(i, 1, 1, n);
            ans ^= (1LL * i * t);
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

st表(2200ms)跑的比個人線段樹慢多了

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 10;
const int MOD = 1 << 30;
int st[N][20], Log[N];
unsigned int X, Y, Z, t[5];
inline unsigned int f() {
    X ^= X << 11;
    X ^= X >> 4;
    X ^= X << 5;
    X ^= X >> 14;
    unsigned int W = X ^ (Y ^ Z);
    X = Y;
    Y = Z;
    Z = W;
    return Z;
}
void init(int n) {
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < 19; j++)
            st[i][j] = 0;
    }
}
void update(int l, int r, int v) {
    int k = Log[r-l+1];
    st[l][k] = max(st[l][k], v);
    st[r-(1<<k)+1][k] = max(st[r-(1<<k)+1][k], v);
}
void gao(int n) {
    for (int j = 18; j >= 1; j--) {
        for (int i = 1; i + (1<<j)-1 <= n; i++) {
            st[i][j-1] = max(st[i][j-1], st[i][j]);
            st[i+(1<<j-1)][j-1] = max(st[i+(1<<j-1)][j-1], st[i][j]);
        }
    }
}
int main() {
    int T, n, m;
    Log[2] = 1;
    for (int i = 3; i < N; i++) Log[i] = Log[i>>1] + 1;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z);
        init(n);
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= 3; j++) t[j] = f();
            int l = min(t[1]%n + 1, t[2]%n + 1);
            int r = max(t[1]%n + 1, t[2]%n + 1);
            int v = t[3] % MOD;
            update(l, r, v);
        }
        gao(n);
        LL ans = 0;
        for (int i = 1; i <= n; i++) {
            int t = st[i][0];
            ans ^= (1LL * i * t);
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

1008 Hills And Valleys

1009 Innocence

1010 Just So You Know

1011 Kaleidoscope

1012 Lost In The Echo

2018 Multi-University Training Contest 6

1001 oval-and-rectangle

思路:積一下分就能夠了,注意保留6位小數,6位以後直接捨去,不要四捨五入,並且long double不能用printf輸出

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

int main() {
    int T, a, b;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &a, &b);
        long double ans = (long double)2.0*(long double)a*asin((long double)1.0) + (long double)2.0*(long double)b;
        LL t = ans * 1000000;
        printf("%.6f\n", t / (double)1000000.0);
    }
    return 0;
}
View Code

1002 bookshelf

1003 Ringland

1004 Shoot Game

1005 black-and-white

1006 foam-transformation

1007 Variance-MST

1008 Rectangle Outline

1009 Werewolf

思路:首先,咱們不能判斷誰是村民,只能判斷哪些人一定是狼,咱們按相似2-sat的建邊,不過是反向的,用dfs判斷哪些點若是是村民,它必定會產生矛盾

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
vector<int>g[N*2];
vector<int>st;
int now, n, vis[N*2];
char s[50];
int dfs(int u, bool f) {
    if(f) vis[u] = true;
    for (int i = 0; i < g[u].size(); i++) {
        if(g[u][i] == now) dfs(g[u][i], true);
        else dfs(g[u][i], f);
    }
}
int main() {
    int T, x;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for (int i = 1; i <= 2*n; i++) g[i].clear(), vis[i] = false;
        st.clear();
        for (int i = 1; i <= n; i++) {
            scanf("%d", &x);
            scanf("%s", s);
            if(s[0] == 'v') g[x].pb(i);
            else g[x+n].pb(i), st.pb(x+n);
        }
        int ans = 0;
        for (int i = 0; i < st.size(); i++) {
            now = st[i] - n;
            dfs(st[i], false);
        }
        for (int i = 1; i <= n; i++) if(vis[i]) ans++;
        printf("0 %d\n", ans);
    }
    return 0;
}
/*
10
3
3 v
3 v
2 w
3
2 w
3 v
2 v
4
2 v
3 v
4 v
3 w

*/
View Code

1010 Chopping hands

1011 sacul

1012 Pinball

2018 Multi-University Training Contest 7

1001 Age of Moyu

1002 AraBellaC

1003 YJJ’s Stack

1004 Go to school

1005 GuGuFishtion

思路:容斥

首先,phi(n) = n * ((p1 - 1) / p1) * ((p2 - 1) / p2) * ... * ((pn - 1) / pn) 其中 pi 是n的素因子

其中, phi(1) = 1

對於a和b兩個數,若是它們都有一個公共的素因子p,假設 a 中有p ^ a1,b中有 p^a2

那麼考慮這個素因子的貢獻

phi(a * b) = (p - 1) * p ^ (a1 + a2 - 1)                   (1) 

phi(a) * phi(b) = (p - 1) ^ 2 * p ^ (a1 + a2 - 2)      (2)

那麼 (1)/ (2) = p / (p -1)

若是a 和 b 每一個共同的素因子 p, 即a1 和 a2 中有一個是0

那麼 (1)/ (2)= 1,沒有貢獻

那麼只需考慮 gcd(a, b) 的貢獻便可

咱們要求 p1 * p2 * .. * pn / ((p1 - 1) * (p2 - 1) * ... * (pn - 1)) ,其中pi是 gcd(a, b) 的素因子

咱們看一下phi(gcd(a, b))等於什麼

phi(gcd(a, b)) = gcd(a, b) * ((p1 - 1) / p1) * ((p2 - 1) / p2) * ... * ((pn - 1) / pn) 其中 pi 是gcd(a, b)的素因子

因此咱們要求的就等於 (1 / phi(gcd(a, b))) * gcd(a, b) = gcd(a, b) / phi(gcd(a, b)

而後問題就轉換成 1 <= a <= n , 1 <= b <= m 中有多少對gcd(a, b) == k

這個能夠用容斥求:

假設f[d] = d | gcd(a, b) 的個數

假設g[d] =  d == gcd(a, b) 的個數

則 g[d] = f[d] - sum(g[i*d], i >= 2) 

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define pf emplace_front
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

const int N = 1e6 + 5;
bool not_pr[N];
int pr[N/5], phi[N], inv[N], f[N];
void get_phi() {
    phi[1] = 1;
    int tot = 0;
    for (int i = 2; i < N; i++) {
        if(!not_pr[i]) {
            phi[i] = i-1;
            pr[tot++] = i;
        }
        for (int j = 0; i * pr[j] < N; j++) {
            not_pr[i*pr[j]] = true;
            if(i % pr[j] == 0) {
                phi[i*pr[j]] = phi[i] * pr[j];
                break;
            }
            else phi[i*pr[j]] = phi[i] * phi[pr[j]];
        }
    }
}
int main() {
    get_phi();
    int T, n, m, mod;
    inv[1] = 1;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d %d", &n, &m, &mod);
        if(n > m) swap(n, m);
        for (int i = 2; i <= n; i++) inv[i] = (mod - mod/i) * 1LL * inv[mod%i] % mod;
        LL ans = 0;
        for (int i = n; i >= 1; i--) {
            f[i] = (1LL * (n/i) * (m/i)) % mod;
            for (int j = i+i; j <= n; j += i) f[i] = (f[i] - f[j] + mod) % mod;
            ans = (ans + 1LL * f[i] * i % mod * inv[phi[i]] % mod) % mod;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

1006 Lord Li's problem

1007 Reverse Game

1008 Traffic Network in Numazu

1009 Tree

1010 Sequence

思路:咱們發現有連續的一段 p/i 是同樣的,並且p/i的不一樣個數是√p級別的,因而咱們分段進行矩陣快速冪

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define pf emplace_front
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

const int MOD = 1e9 + 7;
const int N = 2e5 + 5;
int dp[N];
struct Matrix {
    int a[3][3];
    void init() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++)
                a[i][j] = 0;
        }
    }
    void _init() {
        init();
        for (int i = 0; i < 3; i++) a[i][i] = 1;
    }
}A, B;

Matrix mul(Matrix a, Matrix b) {
    Matrix ans;
    ans.init();
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if(a.a[i][j]) {
                for (int k = 0; k < 3; k++) ans.a[i][k] = (ans.a[i][k] + 1LL * a.a[i][j] * b.a[j][k]) % MOD;
            }
        }
    }
    return ans;
}
Matrix q_pow(Matrix a, int k) {
    Matrix ans;
    ans._init();
    if(k <= 0) return ans;
    while(k) {
        if(k&1) ans = mul(ans, a);
        a = mul(a, a);
        k >>= 1;
    }
    return ans;
}
int main() {
    int T, a, b, c, d, p, n;
    scanf("%d", &T);
    A.init();
    A.a[0][2] = 1;
    A.a[1][0] = 1;
    A.a[2][2] = 1;
    B.init();
    while(T--) {
        scanf("%d %d %d %d %d %d", &a, &b, &c, &d, &p, &n);
        dp[1] = a;
        dp[2] = b;
        if(n <= 50000) {
            for (int i = 3; i <= n; i++) dp[i] = (1LL * c * dp[i-2] + 1LL * d *dp[i-1] + p/i) % MOD;
            printf("%d\n", dp[n]);
        }
        else {
            A.a[0][0] = d;
            A.a[0][1] = c;
            B.a[0][0] = dp[2];
            B.a[1][0] = dp[1];
            for (int i = 3; i <= n;) {
                int j;
                if(p/i == 0) j = n;
                else j = min(n, p/(p/i));
                B.a[2][0] = p/i;
                B = mul(q_pow(A, j-i+1), B);
                i = j+1;
            }
            printf("%d\n", B.a[0][0]);
        }
    }
    return 0;
}
View Code

1011 Swordsman

2018 Multi-University Training Contest 8

1001 Character Encoding

思路:生成函數+廣義二項式定理

隊友代碼:

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
long long POW(long long x,long long n){
    long long re=1,base=x;
    while(n){
        if(n&1)(re*=base)%=mod;
        (base*=base)%=mod;
        n>>=1;
    }
    return re;
}
long long inv[200010],fac[200010],nfac[200010],ninv[200010];
 
void getFac(){
    fac[0]=1,nfac[0]=1;
    for(int i=1;i<=200000;i++)fac[i]=fac[i-1]*i%mod;
    for(int i=1;i<=200000;i++)nfac[i]=(mod+nfac[i-1]*(-i)%mod)%mod;
    inv[200000]=POW(fac[200000],mod-2);
    ninv[200000]=POW(nfac[200000],mod-2);
    for(int i=200000;i>=1;i--)inv[i-1]=inv[i]*i%mod,ninv[i-1]=(mod+ninv[i]*(-i)%mod)%mod;
}
long long C(long long n,long long m){
    if(m<0)return 0;
    long long re=inv[m];
//    re=inv[m]*(n>0?fac[n]:nfac[-n])%mod*(n-m>0?inv[n-m]:ninv[m-n])%mod;
    
    if(n>=0&&m>=0)re=re*fac[n]%mod*inv[n-m]%mod;
    else if(n<0&&m>=0)re=re*ninv[-n-1]%mod*nfac[m-n-1]%mod;
    
//    for(int i=0;i<m;i++)re=(re*(n-i)%mod+mod)%mod;
//    for(int i=1;i<=m;i++)re=(re*(POW(i,mod-2))%mod+mod)%mod;
    return re;
}
long long sign(long long x){
    if(x&1)return -1;
    else return 1;
}
int main(){
    int T;
    getFac();
    cin>>T;
    long long n,m,k;
    for(int t=1;t<=T;t++){
        scanf("%lld%lld%lld",&n,&m,&k);
        long long ans=0;
        for(long long i=0;i<=m;i++){
            (ans+=C(m,i)*sign(m-i)*C(-m,k-i*n)*sign(-m-k+i*n)%mod+mod)%=mod;
        }
        cout<<(ans+mod)%mod<<endl;
    }
    return 0;
}
View Code

1002 Pizza Hub

1003 City Development

1004 Parentheses Matrix

思路:首先,當n和m都是奇數時一個goodness都沒有,隨便構造,其次,當n和m中有一個是偶數時,全部行或者全部列都是構形成匹配的

當n和m都爲偶數時(假設n > m),能夠這樣構造:

咱們發現這樣構造的的goodness是 n + (m - 2) / 2

咱們還能夠這樣構造(犧牲最上面一行和最下面一行以及最左邊一列和最右邊一列來成全中間的全部行和列):

這樣構造的goodness是 n + m - 4

解個不等式: n + (m - 2) / 2 >= n + m - 4

得: m <= 6

綜上所述:

當min(n, m) <= 6 時,採用第一種構造;當min(n, m) > 6時,採用第二種構造

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 222;
char s[N][N];
int main() {
    int T, n, m;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &n, &m);
        if(n%2 == 0 && m%2 == 0 && min(n, m) > 6) {
            for (int i = 1; i <= m; i++) s[1][i] = '(', s[n][i] = ')';
            for (int i = 2; i < n; i++) {
                if((i-1)&1) {
                    for(int j = 1; j <= m; j++) {
                        if(j&1) s[i][j] = '(';
                        else s[i][j] = ')';
                    }
                }
                else {
                    s[i][1] = '(';
                    s[i][m] = ')';
                    for (int j = 2; j < m; j++) {
                        if((j-1)&1) s[i][j] = '(';
                        else s[i][j] = ')';
                    }
                }
            }
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    putchar(s[i][j]);
                }
                puts("");
            }
            continue;
        }
        if(n < m) {
            if(n%2 == 0) {
                for (int j = 1; j <= m; j++) {
                    if(j&1) {
                        s[1][j] = '(';
                        s[n][j] = ')';
                        for (int i = 2; i < n; i++) {
                            if((i-1)&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                    else {
                        for (int i = 1; i <= n; i++) {
                            if(i&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                }
            }
            else if(m%2 == 0) {
                for (int i = 1; i <= n; i++) {
                    if(i&1) {
                        s[i][1] = '(';
                        s[i][m] = ')';
                        for (int j = 2; j < m; j++) {
                            if((j-1)&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                    else {
                        for (int j = 1; j <= m; j++) {
                            if(j&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                }
            }
            else {
                for (int i = 1; i <= n; i++) {
                    for (int j = 1; j <= m; j++)
                        s[i][j] = '(';
                }
            }
        }
        else {
            if(m%2 == 0) {
                for (int i = 1; i <= n; i++) {
                    if(i&1) {
                        s[i][1] = '(';
                        s[i][m] = ')';
                        for (int j = 2; j < m; j++) {
                            if((j-1)&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                    else {
                        for (int j = 1; j <= m; j++) {
                            if(j&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                }
            }
            else if(n%2 == 0) {
                for (int j = 1; j <= m; j++) {
                    if(j&1) {
                        s[1][j] = '(';
                        s[n][j] = ')';
                        for (int i = 2; i < n; i++) {
                            if((i-1)&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                    else {
                        for (int i = 1; i <= n; i++) {
                            if(i&1) s[i][j] = '(';
                            else s[i][j] = ')';
                        }
                    }
                }
            }
            else {
                for (int i = 1; i <= n; i++) {
                    for (int j = 1; j <= m; j++)
                        s[i][j] = '(';
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                putchar(s[i][j]);
            }
            puts("");
        }
    }
    return 0;
}
View Code

1005 Magic Square

1006 Boolean 3-Array

1007 Card Game

1008 K-Similar Strings

1009 Make ZYB Happy

1010 Taotao Picks Apples

思路:先用二分+st表採用dp求出每一個位置日後的遞增序列長度(對於dp[i],二分找到後面第一個比a[i]大的數a[j],而後dp[i] = dp[j] + 1)

再預處理出原序列到當前位置的遞增序列的值以及長度,而後對於每一個詢問p和q,考慮將a[p]改變成q的影響來求答案

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 10;
const int INF = 0x7f7f7f7f;
int a[N], dp[N], mx[N][20], v[N], pre[N], Log[N];
void init(int n) {
    for (int i = 0; i < 19; i++) {
        for (int j = 1; j + (1<<i) - 1 <= n; j++) {
            if(i == 0) mx[j][i] = a[j];
            else mx[j][i] = max(mx[j][i-1], mx[j+(1<<i-1)][i-1]);
        }
    }
}
int query(int l, int r) {
    int k = Log[r-l+1];
    return max(mx[l][k], mx[r-(1<<k)+1][k]);
}
int main() {
    int T, n, M, p, q;
    scanf("%d", &T);
    Log[2] = 1;
    for (int i = 3; i < N; i++) Log[i] = Log[i>>1] + 1;
    while(T--) {
        scanf("%d%d", &n, &M);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        a[n+1] = INF;
        dp[n+1] = 0;
        init(n);
        for (int i = n; i >= 1; i--) {
            int l = i+1, r = n+1, m = l+r >> 1;
            while(l < r) {
                if(query(i+1, m) > a[i]) r = m;
                else l = m+1;
                m = l+r >> 1;
            }
            dp[i] = dp[m] + 1;
        }
        v[0] = 0, pre[0] = 0;
        for (int i = 1; i <= n; i++) {
            if(a[i] > v[i-1]) {
                v[i] = a[i];
                pre[i] = pre[i-1] + 1;
            }
            else v[i]  = v[i-1], pre[i] = pre[i-1];
        }
        for (int i = 0; i < M; i++) {
            scanf("%d %d", &p, &q);
            int ans = pre[p-1];
            if(q > v[p-1]) {
                ans++;
                int l = p+1, r = n+1, m = l+r >> 1;
                while(l < r) {
                    if(query(p+1, m) > q) r = m;
                    else l = m+1;
                    m = l+r >> 1;
                }
                ans += dp[m];
            }
            else {
                int l = p+1, r = n+1, m = l+r >> 1;
                while(l < r) {
                    if(query(p+1, m) > v[p-1]) r = m;
                    else l = m+1;
                    m = l+r >> 1;
                }
                ans += dp[m];
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}
View Code

1011 Pop the Balloons

1012 From ICPC to ACM

2018 Multi-University Training Contest 9

1001 Rikka with Nash Equilibrium

思路:dp,用滾動數組優化一下空間

從大到小填數字,dp[now][i][j]表示當前填了now個數字,選中了i行和j列的方案數

具體轉移看代碼:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 85;
int mod;
int dp[2][N][N];
int main() {
    int T, n, m;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d %d", &n, &m, &mod);
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <= n; j++) {
                for (int k = 0; k <= m; k++)
                    dp[i][j][k] = 0;
            }
        }
        int now = 0;
        dp[now][1][1] = (n*m) % mod;
        for (int i = 2; i <= n*m; i++) {
            for (int j = 1; j <= n; j++) {
                for (int k = 1; k <= m; k++) {
                    dp[now^1][j][k] = 0;
                    dp[now^1][j][k] = (dp[now^1][j][k] + 1LL * k * (n - j + 1) * dp[now][j-1][k] + 1LL * j * (m - k + 1) * dp[now][j][k-1]) % mod;
                    dp[now^1][j][k] = (dp[now^1][j][k] + (j*k - (i-1)) * 1LL * dp[now][j][k]) % mod;
                }
            }
            now ^= 1;
        }
        printf("%lld\n", dp[now][n][m] % mod);
    }
    return 0;
}
View Code

1002 Rikka with Seam

1003 Rikka with APSP

1004 Rikka with Stone-Paper-Scissors

思路:公式 (a' * (c - b) + b' * (a - c) + c' * (b - a)) / (a + b + c)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
pii getAns(ll a,ll b,ll c,ll aa,ll bb,ll cc){
    ll fi=aa*(c-b)+bb*(a-c)+cc*(b-a);
    ll se=a+b+c;
    return pii(fi,se);
}
int main(){
    long long T;
    cin>>T;
    long long a,b,c,aa,bb,cc;
    for(int t=1;t<=T;t++){
        cin>>a>>b>>c>>aa>>bb>>cc;
        pii ans=getAns(a,b,c,aa,bb,cc);
        ll gcd= __gcd(abs(ans.first),ans.second);
        if(gcd==ans.second){
            cout<<ans.first/gcd<<endl;
        }
        else cout<<ans.first/gcd<<'/'<<ans.second/gcd<<endl;
    }
    return 0;
}
View Code

1005 Rikka with Rain

1006 Rikka with Spanning Tree

1007 Rikka with Treasure

1008 Rikka with Line Graph

1009 Rikka with Bubble Sort

1010 Rikka with Time Complexity

1011 Rikka with Badminton

思路:

容斥推出公式:2^a * ((b+d+1)* 2^c + 2^b - (b+1))

一個不行的加起來,減去兩個都不行的

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int MOD = 998244353;
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        if(k&1) ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
    }
    return ans;
}
int main() {
    int T, a, b, c, d;;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d %d %d", &a, &b, &c, &d);
        LL ans = q_pow(2, a) * 1LL *  ( q_pow(2, c) * 1LL *(b + d + 1) % MOD + q_pow(2, b) - (1+b) + MOD) % MOD;
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

 2018 Multi-University Training Contest 10

1001 Problem A.Alkane

1002 Problem B. Beads

1003 Problem C. Calculate

1004 Problem D. Permutation

1005 Problem E. TeaTree

思路:bitset瞎搞

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
vector<int>g[N];
vector<int>f[N];
int v[N], ans[N];
void init() {
    for (int i = 1; i < N; i++) {
        for (int j = i; j < N; j += i) {
            f[j].pb(i);
        }
    }
}
bitset<N> dfs(int u) {
    bitset<N> res;
    for (int t : f[v[u]]) res.set(N - t);
    ans[u] = -1;
    for (int v : g[u]) {
        bitset<N> t = dfs(v);
        ans[u] = max(ans[u], (int)(N - (res&t)._Find_first()));
        res |= t;
    }
    return res;
}
int main() {
    int n, u;
    init();
    scanf("%d", &n);
    for (int i = 2; i <= n; i++) {
        scanf("%d", &u);
        g[u].pb(i);
    }
    for (int i = 1; i <= n; i++) scanf("%d", &v[i]);
    dfs(1);
    for (int i = 1; i <= n; i++) {
        if(ans[i] <= 0) printf("-1\n");
        else printf("%d\n", ans[i]);
    }
    return 0;
}
View Code

1006 Problem F. NewNippori

1007 Problem G. Cyclic

思路:打表找規律

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll a[100005];
void get_num()
{
    a[1]=1;
    a[2]=0;
    a[3]=1;
    a[4]=1;
    a[5]=8;
    a[6]=36;
    for(ll i=7;i<=100000;i++)
    {
        a[i]=(((i-2)*a[i-1])%mod+((i-1)*a[i-2])%mod+((i&1)?1:-1))%mod;
    }
//    for(int i=1;i<=20;i++) cout<<a[i]<<endl;
}
int main()
{
    int t;
    scanf("%d",&t);
    get_num();
    while(t--)
    {
        int n;
        scanf("%d",&n);
//        n-=4;
        cout<<a[n]<<endl;
    }
}
View Code

1008 Problem H. Pow

思路:高精度,用pow(2,n)也能夠,跟計算機存儲浮點數存儲方式有關

double指數位能夠從- 2^10 到 2^10 - 1

import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;

/* Name of the class has to be "Main" only if the class is public. */
public class Main
{
    public static void main (String[] args) 
    {
        Scanner reader = new Scanner(System.in);
        int T, n;
        T = reader.nextInt();
        while(T != 0) {
            T--;
            n = reader.nextInt();
            BigInteger ans = new BigInteger("1");
            for (int i = 1; i <= n; i++) {
                ans = ans.multiply(BigInteger.valueOf(2));
            }
            System.out.println(ans);
        }
        // your code goes here
    }
}
View Code

1009 Problem I. Count

思路:打表找規律,與歐拉函數有關

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 20000100;
int phi[N], prime[N/5];
LL ans[N];
bool not_prime[N];
void Euler()
{
    phi[1]=1;
    int k=0;
    for(int i=2;i< N;i++)
    {
        if(!not_prime[i])
        {
            phi[i]=i-1;
            prime[k++]=i;
        }
        for(int j=0; i*prime[j] < N; j++)
        {
            not_prime[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}
int main() {
    Euler();
    ans[0] = 0;
    for (int i = 1; i < N; i++) {
        if(i&1) ans[i] = ans[i-1] + phi[i]/2;
        else ans[i] = ans[i-1] + phi[i];
    }
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        printf("%lld\n", ans[n]);
    }
    return 0;
}
View Code

1010 Problem J. CSGO

思路:用二進制枚舉絕對值去掉後每一個數前面的加減號。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
struct node {
    int s;
    int x[5];
}a[N], b[N];
bool cmp1(node a, node b) {
    return a.s < b.s;
}
bool cmp2(node a, node b) {
    return a.x[0] < b.x[0];
}
bool cmp3(node a, node b) {
    return a.x[1] < b.x[1];
}
bool cmp4(node a, node b) {
    return a.x[2] < b.x[2];
}
bool cmp5(node a, node b) {
    return a.x[3] < b.x[3];
}
bool cmp6(node a, node b) {
    return a.x[4] < b.x[4];
}
LL mxa[50], mna[50], mxb[50], mnb[50];
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int n, m, k;
        scanf("%d %d %d", &n, &m, &k);
        for (int i = 0; i < (1<<k); i++) mxa[i] = mxb[i] = -INF, mna[i] = mnb[i] = INF;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i].s);
            for (int j = 0; j < k; j++) {
                scanf("%d", &a[i].x[j]);
            }
            for (int j = 0; j < (1<<k); j++) {
                LL t = a[i].s;
                for (int l = 0; l < k; l++) {
                    if(j & (1<<l)) t += a[i].x[l];
                    else t -= a[i].x[l];
                }
                mna[j] = min(mna[j], t);
                mxa[j] = max(mxa[j], t);
            }
        }
        for (int i = 1; i <= m; i++) {
            scanf("%d", &b[i].s);
            for (int j = 0; j < k; j++) {
                scanf("%d", &b[i].x[j]);
            }
            for (int j = 0; j < (1<<k); j++) {
                LL t = b[i].s;
                for (int l = 0; l < k; l++) {
                    if(j & (1<<l)) t += b[i].x[l];
                    else t -= b[i].x[l];
                }
                mnb[j] = min(mnb[j], t);
                mxb[j] = max(mxb[j], t);
            }
        }
        int up = (1<<k) - 1;
        LL ans = 0;
        for (int j = 0; j < (1<<k); j++) {
            ans = max(ans, mna[j] + mnb[up^j]);
            ans = max(ans, mna[j] + mxb[up^j]);
            ans = max(ans, mxa[j] + mnb[up^j]);
            ans = max(ans, mxa[j] + mxb[up^j]);
            //cout << j << " " << ans << endl;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
/*
100
5 5 1
3 3
-5 0
0 -5
5 0
0 5

2 -4
5 0
0 5
-5 0
0 -5

*/
View Code

1011 Problem K. Pow2

1012 Problem L.Videos

牛客

牛客網暑期ACM多校訓練營(第一場)

Monotonic Matrix

思路:找規律

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 2e3 + 10;
const int MOD = 1e9 + 7;
LL dp[N][N], t[2*N][2*N];
LL q_pow(LL n, LL k) {
     LL ans = 1;
     while(k) {
        if(k&1) ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
     }
     return ans;
}
int main() {
    t[1][1] = 3;
    for (int i = 2; i < 2*N; i++) t[1][i] = (t[1][i-1] + i+1) % MOD;
    for (int i = 2; i < N; i++) {
        for (int j = 1; j < N; j++) {
            if(j == 1) t[i][j] = t[j][i];
            else {
                t[i][j] = (t[i][j-1] * t[1][i+j-1] % MOD * q_pow(t[1][j-1], MOD-2)) % MOD;
            }
        }
    }
    int n, m;
    while(~
    scanf("%d %d", &n, &m)) {
        printf("%lld\n", t[n][m]);
    }
    return 0;
}
View Code

Symmetric Matrix

Fluorescent 2

Two Graphs

思路:狀態壓縮

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 100;
pii e1[N], e2[N];
int n, m1, m2, ans;
int vis[10][10], cnt[10], vs[10][10], a[10], t[10][10];
map<int, int>mp;
int main() {
    while( ~ scanf("%d %d %d", &n, &m1, &m2)) {
        mem(vs, 0);
        mem(cnt, 0);
        for (int i = 0; i < m1; i++) {
            scanf("%d %d", &e1[i].fi, &e1[i].se);
            if(e1[i].fi > e1[i].se) swap(e1[i].fi, e1[i].se);
            vs[e1[i].fi][e1[i].se] = 1;
        }
        mem(vis, 0);
        for (int i = 0; i < m2; i++) {
            scanf("%d %d", &e2[i].fi, &e2[i].se);
            if(e2[i].fi > e2[i].se) swap(e2[i].fi, e2[i].se);
            vis[e2[i].fi][e2[i].se] = 1;
        }
 
        int sta = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                sta = sta * 2 + vis[i][j];
            }
        }
        int ans = 0;
        mp.clear();
        for (int i = 1; i <= n; i++) a[i] = i;
        do {
            int s = 0;
            for (int i = 1; i <= n; i++) {
                for (int j = i+1; j <= n; j++) {
                    t[i][j] = 0;
                }
            }
            for (int i = 1; i <= n; i++) {
                for (int j = i+1; j <= n; j++) {
                    if(vs[i][j]) {
                        if(a[i] < a[j]) t[a[i]][a[j]] = 1;
                        else t[a[j]][a[i]] = 1;
                    }
                }
            }
            for (int i = 1; i <= n; i++) {
                for (int j = i+1; j <= n; j++) {
                    s = s * 2 + t[i][j];
                }
            }
            mp[s]++;
        }while(next_permutation(a+1, a+1+n));
        for (auto it = mp.begin(); it != mp.end(); it++) {
            int s = it -> fi;
            if((s & sta) == s) ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}
/*
3 1 2
1 3
1 2
1 3
4 2 3
1 2
1 3
4 1
4 2
4 3
*/
View Code

Removal

Sum of Maximum

Steiner Tree

Longest Path

Substring

Different Integers

思路:莫隊

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e5 + 5;
int a[N], cnt[N], blo, ans, res[N];
struct edge {
    int l, r, bl, id;
    bool operator < (const edge & t) const {
        if(bl == t.bl) return r < t.r;
        else return l < t.l;
    }
}Q[N];
void add(int x) {
    if(!cnt[a[x]]) ans++;
    cnt[a[x]]++;
}
void ded(int x) {
    cnt[a[x]]--;
    if(!cnt[a[x]]) ans--;
}
int main() {
    int n, q;
    while( ~scanf("%d %d", &n, &q)) {
        blo = sqrt(n);
        mem(cnt, 0);
        ans = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            if(!cnt[a[i]]) ans++;
            cnt[a[i]]++;
        }
        for (int i = 1; i <= q; i++)  {
            scanf("%d %d", &Q[i].l, &Q[i].r);
            Q[i].id = i;
            Q[i].l ++;
            Q[i].r --;
            Q[i].bl = (Q[i].l - 1) / blo;
        }
        sort(Q+1, Q+1+q);
        int i = 1, l, r;
        for (i = 1; i <= q; i++) {
            if(Q[i].l <= Q[i].r) {
                l = Q[i].l+1;
                r = Q[i].l;
                break;
            }
            else res[Q[i].id] = ans;
        }
        for (; i <= q; i++) {
            while(l < Q[i].l) add(l++);
            while(l > Q[i].l) ded(--l);
            while(r < Q[i].r) ded(++r);
            while(r > Q[i].r) add(r--);
            //cout << l << " " << r << " " << ans << endl;
            res[Q[i].id] = ans;
        }
        for (int i = 1; i <= q; i++) printf("%d\n", res[i]);
    }
    return 0;
}
/*
10 10
1 2 3 4 5 6 7 8 9 10
4 5
5 6
6 7
8 9
4 6
4 7
4 8
4 9
4 10
4 10
*/
View Code

牛客網暑期ACM多校訓練營(第二場)

run

思路:dp

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e5 + 5;
const int MOD = 1e9 + 7;
LL dp[N][2], sum[N];
int main() {
    int q, k, l, r;
    scanf("%d %d", &q, &k);
    dp[0][0] = 1;
    for (int i = 1; i < N; i++) {
        dp[i][0] += dp[i-1][0] + dp[i-1][1];
        dp[i][0] %= MOD;
        if(i - k >= 0) dp[i][1] += dp[i-k][0];
        dp[i][1] %= MOD;
    }
    sum[0] = 1;
    for (int i = 1; i < N; i++) {
        sum[i] = (sum[i-1] + dp[i][0] + dp[i][1]) % MOD;
    }
    while(q--) {
        scanf("%d %d", &l, &r);
        printf("%lld\n", ((sum[r] - sum[l-1]) % MOD + MOD) % MOD);
    }
    return 0;
}
View Code

discount

message

money

思路:貪心,每次找連續上升的一段

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e5 + 5;
int a[N];
int main() {
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int pre = 1, cnt = 0, now = 0;
        LL ans = 0;
        for (int i = 2; i <= n; i++) {
            if(a[i] >= a[i-1]) {
                now = i;
            }
            else {
                if(now > pre && a[now] != a[pre]){
                    ans += a[now] - a[pre];
                    cnt += 2;
                }
                pre = i;
            }
        }
        if(now > pre && a[now] != a[pre]) ans += a[now] - a[pre], cnt += 2;
        printf("%lld %d\n", ans, cnt);
    }
    return 0;
}
View Code

tree

trade

transform

思路:二分

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 5e5 + 5;
LL pren[N], pres[N], sufn[N], sufs[N];
int n;
LL T;
struct node {
    int x, a;
    bool operator < (const node & t) const {
        return x < t.x;
    }
}a[N];
LL get_pres(int l, int r) {
    return pres[r] - pres[l] - (a[r].x - a[l].x) * pren[l];
}
LL get_sufs(int l, int r) {
    return sufs[l] - sufs[r] - (a[r].x - a[l].x) * sufn[r];
}
bool check(LL m) {
    int mid = 0, r = 0;
    LL cnt1 = (m+1)/2;
    for (int i = 1; i <= n; i++) {
        while(mid <= n && pren[mid] - pren[i-1] < cnt1) mid++;
        if(mid > n) break;
        while(r <= n && pren[r] - pren[i-1] < m) r++;
        if(r > n) break;
        if((get_pres(i-1, mid) + get_sufs(mid, r+1) - (pren[r] - pren[i-1] - m) * (a[r].x - a[mid].x)) * 2 <= T) return true;
        if((get_pres(i-1, mid) + get_sufs(mid, r+1) - (pren[r] - pren[i-1] - m) * (a[i].x - a[mid].x)) * 2 <= T) return true;
    }
//    mid = r = n;
//    for (int i = n; i >= 1; i--) {
//        while(mid >= 1 && sufn[mid] - sufn[i+1] < cnt1) mid--;
//        if(mid < 1) break;
//        while(r >= 1 && sufn[r] - sufn[i+1] < m) r--;
//        if(r < 1) break;
//        if((get_pres(r-1, mid) + get_sufs(mid, i+1) - (pren[i] - pren[r-1] - m) * (a[mid].x - a[r].x)) * 2 <= T) return true;
//        if((get_pres(r-1, mid) + get_sufs(mid, i+1) - (m - pren[i] + pren[r-1]) * (a[i].x - a[mid].x)) * 2 <= T) return true;
//    }
    return false;
}
int main() {
    scanf("%d %lld", &n, &T);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i].x);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i].a);
    sort(a+1, a+1+n);
    a[0].x = 0;
    for (int i = 1; i <= n; i++) {
        pren[i] = pren[i-1] + a[i].a;
        pres[i] = pres[i-1] + (a[i].x - a[i-1].x) * pren[i-1];
    }
    a[n+1].x = 1000000000;
    for (int i = n; i >= 1; i--) {
        sufn[i] = sufn[i+1] + a[i].a;
        sufs[i] = sufs[i+1] + (a[i+1].x - a[i].x) * sufn[i+1];
    }
    LL l = 0, r = 1e10, m = (l + r + 1) >> 1;
    while(l < r) {
        if(check(m)) l = m;
        else r = m-1;
        m = (l + r + 1) >> 1;
//        cout << l << " " << r << endl;
    }
    printf("%lld\n", m);
    return 0;
}
View Code

travel

思路:樹形dp

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 4e5 + 5, M = 5;
int a[N];
vector<int>g[N];
LL F[N][5], G[N][5];
void dfs(int o, int u) {
    LL sum[2][M][M] = {0}, tmp[M][M] = {0};
    int now = 0;
    for (int v : g[u]) {
        if(v != o) {
            dfs(u, v);
            for (int i = 0; i <= 2; i++) {
                for (int j = 0; j <= 3; j++) {
                    tmp[i][j] = 0;
                    sum[now][i][j] = 0;
                }
            }
            for (int i = 0; i <= 3; i++) {
                tmp[0][i] = F[v][i];
                tmp[1][i] = G[v][i];
            }
            for (int i = 0; i <= 2; i++) {
                for (int j = 0; i+j <= 2; j++) {
                    for (int k = 0; k <= 3; k++){
                        for (int l = 0; l+k <= 3; l++) {
                            sum[now][i+j][l+k] = max(sum[now][i+j][l+k], sum[now^1][i][k] + tmp[j][l]);
                            //sum[now][i+j][l+k] = max(sum[now][i+j][l+k], sum[now^1][j][l] + tmp[i][k]);
                        }
                    }
                }
            }
            now ^= 1;
        }
    }
    for (int i = 0; i <= 1; i++) {
        for (int j = 0; j <= 3; j++) {
            G[u][j] = max(G[u][j], sum[now^1][i][j] + a[u]);
        }
    }
    for (int i = 0; i <= 2; i++) {
        for (int j = 1; j <= 3; j++) {
            F[u][j] = max(F[u][j], sum[now^1][i][j-1] + a[u]);
        }
    }
    for (int i = 0; i <= 3; i ++) F[u][i] = max(F[u][i], sum[now^1][0][i]);
}
int main() {
    int n, u, v;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i < n; i++) {
        scanf("%d %d", &u, &v);
        g[v].pb(u);
        g[u].pb(v);
    }
    dfs(0, 1);
    printf("%lld\n", F[1][3]);
    return 0;
}
View Code

car

思路:風車狀

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e5 + 5;
bool r[N], c[N];
int main() {
    int n, m, x, y;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &x, &y);
        r[x] = true;
        c[y] = true;
    }
    int ans = 0;
    if(n % 2) {
        for (int i = 1; i <= n; i++) {
            if(i == n/2 + 1) continue;
            if(!r[i]) ans++;
        }
        for (int i = 1; i <= n; i++) {
            if(i == n/2 + 1) continue;
            if(!c[i]) ans++;
        }
        if(!r[n/2 + 1] || !c[n/2 + 1]) ans++;
    }
    else {
        for (int i = 1; i <= n; i++) if(!r[i]) ans++;
        for (int i = 1; i <= n; i++) if(!c[i]) ans++;
    }
    printf("%d\n", ans);
    return 0;
}
View Code

farm

思路:隨機或者樹狀數組

隨機

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e6 + 5;
const int MOD = 1e9 + 5;
vector<int>a[N];
vector<LL> s1[N], s2[N];
int b1[N], b2[N];
void add(int x, int y, int k) {
    s1[x][y] += b1[k];
    s2[x][y] += b2[k];
}
void del(int x, int y, int k) {
    s1[x][y] -= b1[k];
    s2[x][y] -= b2[k];
}
void cal(int x, int y) {
    s1[x][y] += s1[x-1][y] + s1[x][y-1] - s1[x-1][y-1];
    s2[x][y] += s2[x-1][y] + s2[x][y-1] - s2[x-1][y-1];
}
int main() {
    srand(time(NULL));
    int n, m, T, x1, y1, x2, y2, k;
    scanf("%d %d %d", &n, &m, &T);
    for (int i = 0; i <= n+2; i++) a[i].resize(m+3), s1[i].resize(m+3), s2[i].resize(m+3);
    for (int i = 1; i < N; i++) {
        b1[i] = (random() % MOD) + N;
        b2[i] = (random() % MOD) + N/2;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++)
            scanf("%d", &a[i][j]);
    }
    while(T--) {
        scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &k);
        add(x1, y1, k);
        del(x1, y2+1, k);
        del(x2+1, y1, k);
        add(x2+1, y2+1, k);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cal(i, j);
            if(s1[i][j] % b1[a[i][j]] == 0 && s2[i][j] % b2[a[i][j]] == 0) ans++;
        }
    }
    printf("%d\n", n*m - ans);
    return 0;
}
View Code

樹狀數組

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e6 + 5;
const int MOD = 1e9 + 5;
vector<int> bit[N], id[N], t[N];
vector<bool>vis[N];
vector<pii>pos[N];
int n, m;
struct query {
    int x1, x2, y1, y2;
}Q[N];
void add(int x, int y, int t) {
    for (int i = x; i <= n; i += i&-i) {
        for (int j = y; j <= m; j += j&-j) {
            bit[i][j] += t;
        }
    }
}
int sum(int x, int y) {
    int ans = 0;
    for (int i = x; i; i -= i&-i) {
        for (int j = y; j; j -= j&-j) {
            ans += bit[i][j];
        }
    }
    return ans;
}
int main() {
    int T, k, mx = 0, a;
    scanf("%d %d %d", &n, &m, &T);
    for (int i = 0; i <= n+2; i++) bit[i].resize(m+3), vis[i].resize(m+3), t[i].resize(m+3);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &a);
            pos[a].push_back({i, j});
            mx = max(mx, a);
        }
    }
    for (int i = 0; i < T; i++) {
        scanf("%d %d %d %d %d", &Q[i].x1, &Q[i].y1, &Q[i].x2, &Q[i].y2, &k);
        id[k].push_back(i);
        mx = max(mx, k);
    }
    for (int i = 1; i <= mx; i++) {
        for (int j = 0; j < pos[i].size(); j++) {
            if(sum(pos[i][j].fi, pos[i][j].se) != 0) vis[pos[i][j].fi][pos[i][j].se] = true;
        }
        for (int j = 0; j < id[i].size(); j++) {
            add(Q[id[i][j]].x1, Q[id[i][j]].y1, 1);
            add(Q[id[i][j]].x1, Q[id[i][j]].y2 + 1, -1);
            add(Q[id[i][j]].x2 + 1, Q[id[i][j]].y1, -1);
            add(Q[id[i][j]].x2 + 1, Q[id[i][j]].y2 + 1, 1);
        }
        for (int j = 0; j < pos[i].size(); j++) {
            if(!vis[pos[i][j].fi][pos[i][j].se]) {
                t[pos[i][j].fi][pos[i][j].se] = sum(pos[i][j].fi, pos[i][j].se);
            }
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if(!vis[i][j]) {
                if(t[i][j] != sum(i, j)) ans++;
            }
            else ans++;
        }
    }
    printf("%d\n", ans);
    return 0;
}
View Code

carpet

思路:hash+KMP找最小循環節,而後用二維單調隊列求區間最小

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e6 + 5;
const int MOD = 1e9 + 7;
const int INF = 0x7f7f7f7f;
string s[N];
vector<int>cost[N], mx[N];
int row[N], col[N], nxt[N];
int get_loop(int a[], int n) {
    nxt[0] = -1;
    for (int i = 1; i < n; i++) {
        int j = nxt[i-1];
        while(a[j+1] != a[i] && j >= 0) j = nxt[j];
        if(a[j+1] == a[i]) nxt[i] = j+1;
        else nxt[i] = -1;
    }
    return n - (nxt[n-1]+1);
}
int main() {
    fio;
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) cin >> s[i];
    for (int i = 0; i < n; i++) cost[i].resize(m+2), mx[i].resize(m+2);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
            cin >> cost[i][j];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            row[i] = (233LL * row[i] + s[i][j]) % MOD;
            col[j] = (233LL * col[j] + s[i][j]) % MOD;
        }
    }
    int a = get_loop(col, m), b = get_loop(row, n);
    deque<int>q;
    for (int i = 0; i < n; i++) {
        q.clear();
        for (int j = 0; j < m; j++) {
            while(!q.empty() && cost[i][q.back()] <= cost[i][j]) q.pop_back();
            q.push_back(j);
            while(!q.empty() && q.front() < j - a + 1) q.pop_front();
            mx[i][j] = cost[i][q.front()];
        }
    }
    int ans = INF;
    for (int j = a-1; j < m; j++) {
        q.clear();
        for (int i = 0; i < n; i++) {
            while(!q.empty() && mx[q.back()][j] <= mx[i][j]) q.pop_back();
            q.push_back(i);
            while(!q.empty() && q.front() < i - b + 1) q.pop_front();
            if(i >= b-1) {
                ans = min(ans, mx[q.front()][j]);
            }
        }
    }
    cout << 1LL * ans * (a+1) * (b+1) << endl;
    return 0;
}
View Code

牛客網暑期ACM多校訓練營(第三場)

PACM Team

思路:揹包,用short類型開數組

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define fi first.first.first
#define se first.first.second
#define th first.second
#define fo second
using namespace std;
const int maxn=40;
int p[maxn],a[maxn],c[maxn],m[maxn],g[maxn];
short dp[38][38][38][38][38];
bool cat[38][38][38][38][38];
vector<int> ans;
int main(){
    int n;
    int P,A,C,M;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d%d%d",p+i,a+i,c+i,m+i,g+i);
    scanf("%d%d%d%d",&P,&A,&C,&M);
    int i,j,k,l,q;
    for(i=1;i<=n;i++)
        for(j=0;j<=P;j++)
            for(k=0;k<=A;k++)  
                for(l=0;l<=C;l++)
                    for(q=0;q<=M;q++){
                        if(j>=p[i]&&k>=a[i]&&l>=c[i]&&q>=m[i]){
                            cat[i][j][k][l][q]=1;
                            dp[i][j][k][l][q]=dp[i-1][j-p[i]][k-a[i]][l-c[i]][q-m[i]]+g[i];
                              
                        }
                        if(dp[i-1][j][k][l][q]>=dp[i][j][k][l][q])dp[i][j][k][l][q]=dp[i-1][j][k][l][q],cat[i][j][k][l][q]=0;
                    }
    short ansp,ansa,ansc,ansm;
    int maxans=0;
    for(int j=0;j<=P;j++)
        for(int k=0;k<=A;k++)  
            for(int l=0;l<=C;l++)
                for(int q=0;q<=M;q++)
                    if(dp[n][j][k][l][q]>maxans)ansp=j,ansa=k,ansc=l,ansm=q,maxans=dp[n][j][k][l][q];
    if(maxans==0)return cout<<0,0;
    for(int i=n;i>=1;i--){
        if(cat[i][ansp][ansa][ansc][ansm]){
            ans.push_back(i);
            ansp-=p[i],ansa-=a[i],ansc-=c[i],ansm-=m[i];
        }
    }
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)cout<<ans[i]-1<<' ';
    return 0;
}
View Code

Expected Number of Nodes

Shuffle Cards

思路:splay實現區間反轉

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int read(){
    char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
    while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
int n,m,root;
struct Splay{
    int fa[MAXN],son[MAXN][2],siz[MAXN],add[MAXN];
    void up(int k){
        siz[k]=siz[son[k][0]]+siz[son[k][1]]+1;
    }
    void down(int k){
        if(add[k]){
            swap(son[k][0],son[k][1]);
            add[son[k][0]]^=1;add[son[k][1]]^=1;
            add[k]=0;
        }
    }
    void rotate(int x,int &k){
        int f=fa[x],gran=fa[f],opt;
        opt=(son[f][1]==x);
        if(f==k) k=x;else son[gran][son[gran][1]==f]=x;
        son[f][opt]=son[x][opt^1];fa[son[f][opt]]=f;
        son[x][opt^1]=f;fa[f]=x;fa[x]=gran;
        siz[x]=siz[f];up(f);
    }
    void splay(int x,int &k){
        while(x!=k){
            int f=fa[x],gran=fa[f];
            if(f!=k) rotate((son[f][0]==x)^(son[gran][0]==f)?x:f,k);
            rotate(x,k);
        }
    }
    void build(int l,int r,int f){
        if(l>r) return;
        int mid=(l+r)>>1;if(mid<f) son[f][0]=mid;else son[f][1]=mid;
        fa[mid]=f;siz[mid]=1;
        if(l==r) return;
        build(l,mid-1,mid);build(mid+1,r,mid);
        up(mid);
    }
    int find(int x,int k){
        down(x);int s=siz[son[x][0]];
        if(s+1==k) return x;
        if(k<=s) return find(son[x][0],k);
        else return find(son[x][1],k-s-1);
    }
    void revers(int l,int r){
        int x=find(root,l),y=find(root,r+2);
        splay(x,root);splay(y,son[root][1]);
        int pl=son[y][0];add[pl]^=1;
    }
}T;
int main()
{
    n=read();m=read();
    root=(n+3)>>1;T.build(1,n+2,root);
    for(int i=1;i<=m;i++){
        int l=read(),r=read();
        r=l+r-1;
        T.revers(1,l-1);
        T.revers(l,r);
        T.revers(1,r);
    }
    for(int i=2;i<=n+1;i++) printf("%d ",T.find(root,i)-1);
    return 0;
}
View Code

Encrypted String Matching

Sort String

思路:字符串hash+排序

代碼:

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
typedef pair<ULL,ULL> pll;
typedef pair<int,int> pii;
const int maxn=1000010;
const int base=233;
char s[maxn];
ULL POW[maxn];
pll Hash[maxn];
pii p[maxn];
vector<int> vec[maxn];
int main(){
    scanf("%s",s);
    int n=strlen(s);
    ULL now=0;
    POW[0]=1;
    for(int i=1;i<=n;++i)POW[i]=POW[i-1]*base;
    for(int i=0;i<n;++i)now=now*base+(s[i]-'a'+1);
    for(int i=0;i<n;i++){
        Hash[i]={now,(ULL)i};
        now=now-(s[i]-'a'+1)*POW[n-1];
        now=now*base+(s[i]-'a'+1);
    }
    sort(Hash,Hash+n);
    int anscnt=0;
    for(int i=0;i<n;i++){
        if(!i||Hash[i-1].first!=Hash[i].first)++anscnt,p[anscnt]={Hash[i].second,anscnt};
        vec[anscnt].emplace_back(Hash[i].second);
    }
    sort(p+1,p+1+anscnt);
    printf("%d\n",anscnt);
    for(int i=1;i<=anscnt;i++){
        printf("%d ",vec[p[i].second].size());
        for(auto w:vec[p[i].second]){
            printf("%d ",w);
        }
        puts("");
    }
    return 0;
}
View Code

Sum Of Digit

Coloring Tree

Diff-prime Pairs

思路:枚舉小於n的素數,每一個素數和比它小的素數匹配,最後答案乘2

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e7 + 5;
bool vis[N];
vector<int>p;
void seive() {
    for (int i = 2; i < N; i++) {
        if(!vis[i]) {
            p.push_back(i);
            for (int j = i+i; j < N; j += i) vis[j] = true;
        }
    }
}
int main() {
    seive();
    int n;
    scanf("%d", &n);
    LL ans = 0;
    for (int i = 0; i < p.size(); i++) {
        if(p[i] > n) break;
        ans += n/p[i] * 1LL * i;
    }
    ans *= 2; 
    printf("%lld\n", ans);
    return 0;
}
View Code

Expected Size of Random Convex Hull

Distance to Work

牛客網暑期ACM多校訓練營(第四場)

Ternary String

Interval Revisited

Chiaki Sequence Reloaded

Another Distinct Values

思路:構造,花了幾個小時想了一個超複雜的構造TAT,看看別人的構造,感受本身蠢哭了

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 555;
int a[N][N];
map<int, int>mp;
bool check(int n) {
    mp.clear();
 
    for (int i = 1; i <= n; i++) {
        int s = 0;
        for (int j = 1; j <= n; j++) {
            s += a[i][j];
        }
        mp[s]++;
    }
 
    for (int i = 1; i <= n; i++) {
        int s = 0;
        for (int j = 1; j <= n; j++) {
            s += a[j][i];
        }
        mp[s]++;
    }
    if(mp.size() == n*2) return true;
    else return false;
}
int main() {
    fio;
    int T, n;
    cin >> T;
    while(T--) {
        cin >> n;
        if(n&1) {
            cout << "impossible" << endl;
            continue;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++)
                a[i][j] = -1;
        }
        for (int i = 1; i <= n/2; i++) {
            for (int j = 1; j <= n/2; j++) {
                a[i][j] = 1;
                a[i+n/2][j+n/2] = -1;
                if(i + j > n/2 + 1) a[i][j+n/2] = 0;
                else a[i][j+n/2] = 1;
            }
        }
        int tot = n/2, cnt, res;
        if(tot&1) cnt = tot/2+1;
        else cnt = tot/2;
        res = tot - cnt;
        for (int i = 1; i <= cnt; i++) {
            for (int j = 1; j <= cnt; j++) {
                if(i + j > cnt + ((tot+1)%2)) a[i+tot][j] = 0;
                else a[i+tot][j] = 1;
            }
        }
        for (int i = 1; i <= res; i++) {
            for (int j = 1; j <= res; j++) {
                if(i + j > res) a[i+tot+cnt][j+cnt] = 0;
                else  a[i+tot+cnt][j+cnt] = -1;
            }
        }
        cout << "possible" << endl;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++)
                cout << a[i][j] << " ";
            cout << endl;
        }
 
    }
    return 0;
}
View Code

Skyline

Beautiful Garden

思路:模擬

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long LL;
 
char s[2005][2005];
 
bool check(char a,char b, char c,char d)
{
    if(a==b&&a==c&&a==d) return true;
    return false;
}
 
int main()
{
    int t;
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) scanf("%s",s[i]);
            int Maxc=INT_MAX;
            int Maxr=INT_MAX;
            for(int i=0;i<n;i++)
            {
                int cnt=0;
                for(int j=0;j<m/2;j++)
                {
                    if(s[i][j]==s[i][m-j-1]) cnt++;
                    else {
                        cnt++;
                        break;
                    }
                }
                Maxr=min(Maxr,cnt);
            }
            for(int i=0;i<m;i++)
            {
                int cnt=0;
                for(int j=0;j<n/2;j++)
                {
                    if(s[j][i]==s[n-j-1][i]) cnt++;
                    else {
                        cnt++;
                        break;
                    }
                }
                Maxc=min(Maxc,cnt);
            }
            Maxc--;
            Maxr--;
            printf("%d\n",Maxc*Maxr);
        }
    }
}
View Code

Maximum Mode

思路:統計一下出現次數爲i的數的個數,而後從小到大枚舉數a[i],檢查一下將全部出現次數大於等於a[i]出現次數的數刪掉成都小於a[i]的個數,可行就更新答案。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e5 + 5 ;
int a[N];
int t[N];
LL sum[N];
int main() {
    int T, n, m;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++) scanf("%d", &a[i]);
        for (int i = 0; i <= n; i++) t[i] = 0;
        sort(a, a+n);
        int now = 1;
        for (int i = 1; i < n; i++) {
            if(a[i] != a[i-1]) {
                t[1]++;
                t[now+1]--;
                now = 1;
            }
            else now++;
        }
        t[1]++;
        t[now+1]--;
        now = 1;
        for (int i = 1; i <= n; i++) t[i] += t[i-1];
        for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + t[i];
        int ans = -1;
        for (int i = 1; i < n;i++) {
            if(a[i] != a[i-1]) {
                if(t[now] - 1 + sum[n] - sum[now] <= m) ans = a[i-1];
                now = 1;
            }
            else now++;
        }
        if(t[now] - 1 + sum[n] - sum[now] <= m) ans = a[n-1];
        printf("%d\n", ans);
    }
    return 0;
}
View Code

Double Palindrome

Permutation

Hash Function

牛客網暑期ACM多校訓練營(第五場) 

gpa

思路:01分數規劃

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e5 + 5;
const double eps = 1e-7;
int n, k;
pii a[N];
double t[N];
bool check(double m) {
    for (int i = 0; i < n; i++) t[i] = (double)a[i].fi*a[i].se - m*a[i].fi;
    sort(t, t+n);
    double tt = 0;
    for (int i = k; i < n; i++) tt += t[i];
    //cout<< fixed << setprecision(6)<< tt << endl;
    return tt >= 0;
}
int main() {
    scanf("%d %d", &n, &k);
    for (int i = 0; i < n; i++) scanf("%d", &a[i].fi);
    for (int i = 0; i < n; i++) scanf("%d", &a[i].se);
    double l = 0, r = 1e4 + 5, m = (l+r)/2;
    while(l + eps< r) {
        if(check(m)) l = m;
        else r = m;
        m = (l+r) / 2;
    }
    printf("%.10f\n", m);
    return 0;
}
View Code

div

grf

inv

room

take

思路:考慮每一個位置對答案的貢獻,但前位置被替換當且僅當前面全部比當前小的都沒有被替換(即以前比當前小的盒子的鑽石都沒有鑽石,有1-pj的機率),這個用樹狀數組維護個前綴積就能夠了

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
const int MOD = 998244353;
pii a[N];
LL bit[N];
int n;
vector<int>vc;
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        if(k&1) ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
    }
    return ans;
}
void add(int x, LL y) {
    while(x <= n) bit[x] *= y, bit[x] %= MOD, x += x&-x;
}
LL sum(int x) {
    LL ans = 1;
    while(x)  ans *= bit[x], ans %= MOD, x -= x&-x;
    return ans;
}
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d %d", &a[i].fi, &a[i].se), vc.pb(a[i].se);
    sort(vc.begin(), vc.end());
    vc.erase(unique(vc.begin(), vc.end()), vc.end());
    for (int i = 0; i < n; i++) a[i].fi = (1LL * a[i].fi * q_pow(100, MOD-2)) % MOD, a[i].se = lower_bound(vc.begin(), vc.end(), a[i].se) - vc.begin(), a[i].se = n - a[i].se;
    for (int i = 0; i <= n; i++) bit[i] = 1;
    LL ans = 0;
    for (int i = 0; i < n; i++) {
        ans = (ans + a[i].fi * sum(a[i].se - 1)) % MOD;
        add(a[i].se, (1 - a[i].fi) % MOD);
    }
    ans = (ans + MOD) % MOD;
    printf("%lld\n", ans);
    return 0;
}
View Code

max

思路:找第一個i和n互質,質數之間距離很短

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

int main() {
    fio;
    int c, n;
    cin >> c >> n;
    n /= c;
    for (int i = n; i >= 1; i--) {
        if(__gcd(i, n) == 1) {
            cout << 1LL * n * i * c * c << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}
View Code

subseq

vcd

思路:首先,一個點的集合確定能夠,其次,二個點若是想知足題意,那麼y要求不一樣,三點的集合若是想知足題意,那麼要三個點構成「<」形狀,最後,超過三個點的集合都不能夠。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
const int MOD = 998244353;
pii a[N];
vector<int>vc;
int n, t[N], bit[N];
void add(int x) {
    while(x <= n) bit[x]++, x += x&-x;
}
int sum(int x) {
    int ans = 0;
    while(x) ans += bit[x], x -= x&-x;
    return ans;
}
bool cmp(pii a, pii b) {
    return a.fi > b.fi;
}
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        if(k&1) ans = (ans * n) % MOD;
         n = (n * n) % MOD;
         k >>= 1;
    }
    return ans;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d %d", &a[i].fi, &a[i].se), vc.pb(a[i].se);
    sort(vc.begin(), vc.end());
    vc.erase(unique(vc.begin(), vc.end()), vc.end());
    for (int i = 1; i <= n; i++) a[i].se = lower_bound(vc.begin(), vc.end(), a[i].se) - vc.begin() + 1, t[a[i].se]++;
    sort(a+1, a+1+n, cmp);
    LL ans = 0;
    for (int i = 1; i <= n; i++) ans += 1LL*t[i]*(n-t[i]), ans %= MOD;
    ans = (ans * q_pow(2, MOD-2)) % MOD;
    ans = (ans + n) % MOD;
    int pos = 1;
    for (int i = 1; i <= n; i++) {
        if(a[i].fi != a[i-1].fi) {
            while(pos < i) {
                add(a[pos++].se);
            }
        }
        int up = sum(n) - sum(a[i].se);
        int down = sum(a[i].se - 1);
        ans += 1LL * up * down;
        ans %= MOD;
    }
    printf("%lld\n", ans);
    return 0;
}
View Code

plan

思路:答案確定是某一種房間選了不少,咱們暴力房間少的那一個,3個就夠了

View Code

牛客網暑期ACM多校訓練營(第六場) 

Singing Contest

思路:模擬+貪心,每次歌手都唱大於對方最大值的歌

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 2e4 + 5;
set<int>s[N];
int mx[N];
bool vis[N];
int main() {
    int T, n, t;
    scanf("%d", &T);
    for (int cs = 1; cs <= T; cs++) {
        scanf("%d", &n);
        mem(mx, 0);
        for (int i = 1; i <= (1<<n); i++) {
            s[i].clear();
            for (int j = 1; j <= n; j++) {
                scanf("%d", &t);
                s[i].insert(t);
                mx[i] = max(mx[i], t);
            }
        }
        mem(vis, false);
        for (int i = 1; i <= n; i++) {
            int last = -1;
            for (int j = 1; j <= (1<<n); j++) {
                if(!vis[j]) {
                    if(last == -1) last = j;
                    else {
                        int mm = mx[last], mmm = mx[j];
                        if(mm > mmm) {
                            vis[j] = true;
                            auto it = s[last].lower_bound(mmm);
                            s[last].erase(it);
                            mx[last] = 0;
                            for (auto t : s[last]) mx[last] = max(mx[last], t);
                        }
                        else {
                            vis[last] = true;
                            auto it = s[j].lower_bound(mm);
                            s[j].erase(it);
                            mx[j] = 0;
                            for (auto t : s[j]) mx[j] = max(mx[j], t);
                        }
                        last = -1;
                    }
                }
            }
        }
        for (int i = 1; i <= (1<<n); i++)
        if(!vis[i]) {
            printf("Case #%d: %d\n", cs, i);
            break;
        }
    }
    return 0;
}
View Code

Endless Pallet

Generation I

思路:考慮第i次操做i ~ n的全部集合都加相同的數,因此咱們只考慮每一個數第一次出如今哪裏,由於若是這個數在後面有沒有出現過是沒有關係的,後面的全部集合都有這個數

考慮總共出現了k個數,第一個位置確定出現了一個數,因此從n-1個位置中選k-1個位置,再加上第一個位置構成k個位置,做爲這k個數第一次出現的位置,總共有C(n-1, k-1)中

而後考慮這k個數有多少種可能,有A(m, k)可能,因此對於出現k個數,有C(n-1, k-1) * A(m, k)中可能,而後將k從1枚舉min(n, m)求個和就能夠了

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e6 + 5;
const int MOD = 998244353;
int inv[N];
void init() {
    inv[1] = 1;
    for (int i = 2; i < N; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD;
}
int main() {
    init();
    int T;
    LL n, m;
    scanf("%d", &T);
    for (int cs = 1; cs <= T; cs++) {
        scanf("%lld %lld", &n, &m);
        int up = min(n, m);
        LL ans = 0, C = 1, A = m%MOD;
        for (int i = 1; i <= up; i++) {
            ans = (ans + C * A) % MOD;
            n--;
            m--;
            C = ((C * n) % MOD * inv[i]) % MOD;
            A = (A * m) % MOD;
        }
        printf("Case #%d: %lld\n", cs, ans);
    }
    return 0;
}
View Code

Bulbasaur

思路:發現每一個身體只能連一個頭,因此對於每一個身體選一個最大的權值,它連哪一個頭都無所謂,這樣是最優的

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e5 + 5;
int mx[N];
int main() {
    int T, a, b, c, n, m, k;
    scanf("%d", &T);
    for (int cs = 1; cs <= T; cs++) {
        scanf("%d %d %d", &n, &m, &k);
        for (int i = 1; i <= n; i++) mx[i] = 0;
        for (int i = 0; i < k; i++) {
            scanf("%d %d %d", &a, &b, &c);
            mx[b] = max(c, mx[b]);
        }
        LL ans = 0;
        for (int i = 1; i <= m; i++) ans += mx[i];
        printf("Case #%d: %lld\n", cs, ans);
    }
    return 0;
}
View Code

Charmander

Squirtle

Pikachu

Eevee

Team Rocket

Heritage of skywalkert

思路:因爲數據隨機,因此最大的幾個數有很大可能互質,因此挑出最大的幾個數兩兩求lcm取最大,能夠用stl裏面的nth_element(),很強大

若是用set的話,注意保存一下當前set的最小值,與最小值判斷一下需不須要加進set,不然的化常數太大會超時

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
unsigned int  A,B,C;
unsigned int  x=A,y=B,z=C;
inline unsigned int  tang()
{
    unsigned int  t;
    x^=x<<16;
    x^=x>>5;
    x^=x<<1;
    t=x;
    x=y;
    y=z;
    z=t^x^y;
    return z;
}
unsigned int  num[10000005];
set<unsigned int>mx;
inline unsigned long long gcd(unsigned long long a, unsigned long long b) {
    return b ? gcd(b, a%b): a;
}
inline unsigned long long lcm(unsigned long long x,unsigned long long y)
{
    return x/__gcd(x,y)*y;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    for(int tt=1;tt<=t;tt++)
    {
        int n;
        cin>>n>>A>>B>>C;
        x=A,y=B,z=C;
        mx.clear();
        unsigned int mn;
        for(int i=1;i<=n;i++)
        {
            num[i]=tang();
            if(mx.size() < 20) mx.insert(num[i]), mn = *mx.begin();
            else {
                if(num[i] > mn) {
                    mx.insert(num[i]);
                    mx.erase(mx.begin());
                    mn = *mx.begin();
                }
            }
        }
        unsigned long long Max=0;
        vector<unsigned int>vc;
        for (auto x:mx) vc.push_back(x);
        for (int i = 0; i < vc.size(); i++) {
            for (int j = i+1; j < vc.size(); j++) {
                Max = max(Max, lcm(vc[i], vc[j]));
            }
        }
        cout<<"Case #"<<tt<<": "<<Max<<endl;
    }
    return 0;
}
View Code

牛客網暑期ACM多校訓練營(第七場)

Minimum Cost Perfect Matching

思路:對於每一個i找比i小的~i,將兩個鏈接起來,這樣最小花費是0

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 5e5 + 5;
bool vis[N];
int a[N];
int main() {
    int n;
    scanf("%d", &n);
    for (int i = n - 1; i >= 0; i--) {
        int t = 0;
        bool f = false;
        for (int j = 29; j >= 0; j--) {
            if((i & (1 << j)) == 0) {
                if(f) t = t*2 + 1;
            }
            else {
                f = true;
                t = t*2;
            }
        }
        if(!vis[i] && !vis[t]) {
            a[i] = t;
            a[t] = i;
            vis[t] = true;
            vis[i] = true;
        }
    }
    for (int i = 0; i < n; i++) printf("%d%c", a[i], " \n"[i==n]);
    return 0;
}
View Code

Birthday Problem

Bit Compression

思路:搜索優化,預處理出最後三步的結果

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb emplace_back
#define pf emplace_front
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

const int N = (1<<16) + 10, M = (1<<20) + 10;
bool t[20][M];
char s[M];
int dp[5][N], ans = 0;
void init(int n) {
    int up = 1;
    for (int i = 0; i < n; i++) up = up * 3;
    for (int i = 0; i < (1<<(1<<n)); i++) {
        for (int j = 0; j < (1<<n); j++) {
            if(i & (1<<j)) t[n][j] = 1;
            else t[n][j] = 0;
        }
        for (int j = 0; j < up; j++) {
            int tmp = j;
            for (int k = n-1; k >= 0; k--) {
                for (int l = 0; l < (1<<k); l++) {
                    if(tmp%3 == 0) t[k][l] = t[k+1][l*2]^t[k+1][l*2+1];
                    else if(tmp%3 == 1) t[k][l] = t[k+1][l*2]&t[k+1][l*2+1];
                    else t[k][l] = t[k+1][l*2]|t[k+1][l*2+1];
                }
                tmp /= 3;
            }
            dp[n][i] += t[0][0];
        }
    }
}
void dfs(int n) {
    for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]^t[n+1][i*2+1];
    if(n == 3) {
        int st = 0;
        for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i];
        ans += dp[n][st];
    }
    else dfs(n-1);
    for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]&t[n+1][i*2+1];
    if(n == 3) {
        int st = 0;
        for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i];
        ans += dp[n][st];
    }
    else dfs(n-1);
    for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]|t[n+1][i*2+1];
    if(n == 3) {
        int st = 0;
        for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i];
        ans += dp[n][st];
        return ;
    }
    else dfs(n-1);
}
int main() {
    int n;
    scanf("%d", &n);
    scanf("%s", s);
    init(min(n, 3));
    if(n <= 3) {
        int st = 0;
        for (int i = 0; i < (1<<n); i++) st = st*2 + (s[i] == '1');
        printf("%d\n", dp[n][st]);
    }
    else {
        for (int i = 0; i < (1<<n); i++) t[n][i] = s[i] == '1';
        dfs(n-1);
        printf("%d\n", ans);
    }
    return 0;
}
View Code

Inverse Inverse Problem

Counting 4-Cliques

思路:打表能夠發現當k很大時能夠由t個點的徹底圖加上另外5個點與t個點中的部分點相連構成k個4元組,即存在t, a, b, c, d, e,

使得C(t, 4) + C(a, 3) + C(b, 3) + C(c, 3) + C(d, 3)+ C(e, 3) == k

預處理C(e, 3), 暴力枚舉a,b, c, d

或者預處理C(d, 3) + C(e, 3) , 暴力枚舉a,b, c 

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

int C4[100], C3[100], t;
int C(int n, int m) {
    int ans = 1;
    if(n < m) return 0;
    for (int i = n; i >= n-m+1; i--) ans *= i;
    for (int i = 1; i <= m; i++) ans /= i;
    return ans;
}
void solve(int a, int b, int c, int d, int e) {
    printf("%d %d\n", t+5, C(t, 2) + a + b + c + d + e);
    for (int i = 1; i <= t; i++) {
        for (int j = i+1; j <= t; j++)
            printf("%d %d\n", i, j);
    }
    for (int i = 1; i <= a; i++) printf("%d %d\n", i, t+1);
    for (int i = 1; i <= b; i++) printf("%d %d\n", i, t+2);
    for (int i = 1; i <= c; i++) printf("%d %d\n", i, t+3);
    for (int i = 1; i <= d; i++) printf("%d %d\n", i, t+4);
    for (int i = 1; i <= e; i++) printf("%d %d\n", i, t+5);
}
map<int, pii>mp;
int main() {
    int k;
    scanf("%d", &k);
    t = 4;
    for (int i = 3; i <= 80; i++) C4[i] = C(i, 4), C3[i] = C(i, 3);
    while(C4[t+1] <= k) t++;
    t = min(t, 70);
    for (int i = 2; i <= t; i++) {
        for (int j = 2; j <= t; j++) {
            mp[C3[i] + C3[j]] = {i, j};
        }
    }
    for (int i = 2; i <= t; i++) {
        for (int j = i; j <= t; j++) {
            for (int l = j; l <= t; l++) {
                if(mp.find(k - C4[t] - C3[i] - C3[j] - C3[l]) != mp.end()) {
                    solve(i, j, l, mp[k - C4[t] - C3[i] - C3[j] - C3[l]].fi, mp[k - C4[t] - C3[i] - C3[j] - C3[l]].se);
                    return 0;
                }
            }
        }
    }
    return 0;
}
View Code

Mindiff and Maxdiff

Rock-Paper-Scissors Tournament

Class Division

Tree Subset Diameter

Sudoku Subrectangles

思路:O(n*m)處理每一個點往右能到哪裏,往下能到哪裏,而後O(52*n*m)對於每一個點往右掃列最小,而後往下求行最小

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

const int N = 1e3 + 5;
char s[N][N];
int a[N][N], r[N][N], d[N][N], mn[N][N];
int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%s", s[i]+1);
        for (int j = 1; j <= m; j++)
            if(isupper(s[i][j])) a[i][j] = s[i][j] - 'A' + 26;
            else a[i][j] = s[i][j] - 'a';
    }
    for (int i = 1; i <= n; i++) {
        LL st = 0;
        int pre = 1;
        for (int j = 1; j <= m; j++) {
            if(j > 1) st ^= 1LL << a[i][j-1];
            r[i][j] = m;
            bool f = true;
            for (int k = pre; k <= m; k++) {
                if(st & (1LL << a[i][k])) {
                    f = false;
                    r[i][j] = k-1;
                    pre = k;
                    break;
                }
                st |= 1LL << a[i][k];
            }
            if(f) pre = m+1;
        }
    }
    for (int j = 1; j <= m; j++) {
        LL st = 0;
        int pre = 1;
        for (int i = 1; i <= n; i++) {
            if(i > 1) st ^= 1LL << a[i-1][j];
            d[i][j] = n;
            bool f = true;
            for (int k = pre; k <= n; k++) {
                if(st & (1LL << a[k][j])) {
                    f = false;
                    d[i][j] = k-1;
                    pre = k;
                    break;
                }
                st |= 1LL << a[k][j];
            }
            if(f) pre = n+1;
        }
    }
    LL ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            mn[i][j] = d[i][j];
            for (int k = j+1; k <= r[i][j]; k++) {
                mn[i][k] = min(mn[i][k-1], d[i][k]);
            }
            int now = r[i][j];
            for (int k = i; k <= d[i][j]; k++) {
                now = min(now, r[k][j]);
                while(mn[i][now] < k && now >= j) now --;
                if(now < j) break;
                ans += now - j + 1;
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}
View Code

牛客網暑期ACM多校訓練營(第八場)

Connecting segments

Filling pools

oeis公式

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head


const int MOD = 998244353;
const int N = 3e5 + 5;
LL C[N], NN[N], inv[N], p[N], ans = 0;
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
    }
    return ans;
}
void init(int n) {
    n--;
    inv[1] = 1;
    for (int i = 2; i <= n; i++) inv[i] = (MOD - MOD/i) * inv[MOD%i] % MOD;
    p[0] = 1;
    for (int i  = 1; i <= n; i++) p[i] = (p[i-1] * 2) % MOD;
    C[0] = 1;
    for (int i = 1; i <= n; i++) C[i] = ((C[i-1] * (n-i+1)) % MOD * inv[i]) % MOD;
    for (int i = 1; i <= n; i++) NN[i] = (C[i] * C[i-1]) % MOD * inv[n] % MOD;
    for (int i = 1; i <= n; i++) ans = (ans + NN[i] * p[n-i+1]) % MOD;
}
int main() {
    int n;
    scanf("%d", &n);
    if(n == 1) return 0*puts("1");
    init(n);
    printf("%lld\n", ans);
    return 0;
}
View Code

Counting paths

Compressing data

Touring cities

Protecting lawn

Counting regions

思路:立體幾何歐拉公式:V - E + F = 2 (V:頂點個數, E:邊條數, F:面個數,怎麼記憶呢,維數爲0的點加上維數爲2的面減去維數爲1的線等於2)

F = E -  V + 2

首先,將平面圖當作立體圖(以正多邊形爲底的立體圖),那麼問題就轉換成已知點個數和邊條數來求多面體的面有多少個

內部交點個數(從n個點中選4個頂點連起來):C(n, 4)

因此定點個數:C(n, 4) + n

每一個內部交點會多產生兩條邊,因此邊個數: C(n, 2) + C(n, 4) * 2

因此F = E - V + 2 = (C(n, 2) + C(n, 4) * 2) - (C(n, 4) + n)  + 2 = C(n, 2) + C(n, 4) - n + 2 

減去底面因此要減一

答案爲C(n, 2) + C(n, 4) - n + 1

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

const int MOD = 1e9 + 7;
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        if(k&1) ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
    }
    return ans;
}
LL C(int n, int m) {
    LL ans = 1;
    for (int i = n; i >= n-m+1; i--) ans = (ans * i) % MOD;
    for (int i = 1; i <= m; i++) ans = (ans * q_pow(i, MOD-2)) % MOD;
    return ans;
}
int main() {
    int n;
    cin >> n;
    LL ans = (C(n, 4) + C(n, 2) - n + 1 + MOD) % MOD;
    cout << ans << endl;
    return 0;
}
View Code

Playing games

Permuting cows

Calculating sums

Decoding graphs

牛客網暑期ACM多校訓練營(第九場)

Circulant Matrix

思路:FWT

隊友代碼:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[530000],b[530000],tot,x,ha=1e9+7,inv2;
int qpow(int a,int b)
{
    int ans=1;
    while(b){if(b&1)ans=ans*a%ha;a=a*a%ha,b>>=1;}
    return ans;
}
void fwt(int *a,int n,int t)
{
    for(int i=1;i<n;i<<=1)
    {
        for(int j=0;j<n;j+=(i<<1))
        for(int k=j;k<i+j;k++)
        {
            int x=a[k],y=a[k+i];
               
            a[k]=(x+y)%ha,a[k+i]=(x-y+ha)%ha;
            if(t)a[k]=a[k]*inv2%ha,a[k+i]=a[k+i]*inv2%ha;
        }
    }
       
}
signed main()
{
    scanf("%lld",&n);
    inv2=qpow(2,ha-2);
    for(int i=0;i<n;i++)scanf("%lld",&a[i]);
    for(int i=0;i<n;i++)scanf("%lld",&b[i]);
    fwt(a,n,0);fwt(b,n,0);
    for(int i=0;i<n;i++)b[i]=b[i]*qpow(a[i],ha-2)%ha;
    fwt(b,n,1);
    for(int i=0;i<n;i++)printf("%lld\n",b[i]);
    return 0;
}
View Code

Enumeration not optimization

Gambling

The number of circuits

Music Game

思路:dp

狀態定義:dp[i][0]表示到第i位以0結尾的指望分數,dp[i][1]表示到第i位以1結尾的指望分數

狀態轉移:dp[i][0] = (1 - p[i]) * (dp[i-1][0] + dp[i-1][1])

dp[i][1] = ∑ ( ∏p[k](j < k <= i) * (dp[j][0] + (1 -  p[j]) * (i - j)^m)) (0<= j < i)

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head
 
const int N = 1e3 + 5;
const int MOD = 1e9 + 7;
LL p[N], pp[N], dp[N][2];
LL q_pow(LL n, LL k) {
    LL ans = 1;
    while(k) {
        if(k&1) ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        k >>= 1;
    }
    return ans;
}
int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%lld", &p[i]);
    for (int i = 0; i <= n; i++) p[i] = (p[i] * q_pow(100, MOD-2)) % MOD, pp[i] = (1 - p[i] + MOD) % MOD;
    dp[0][0] = dp[1][0] = 0;
    for (int i = 1; i <= n; i++) {
        LL t = p[i];
        dp[i][1] = 0;
        for (int j = i-1; j >= 0; j--) {
            dp[i][1] = (dp[i][1] + t * (dp[j][0] + pp[j] * q_pow(i-j, m) % MOD) % MOD) % MOD;
            t = (t * p[j]) % MOD;
        }
        dp[i][0] = (pp[i] * (dp[i-1][0] + dp[i-1][1])) % MOD;
    }
    printf("%lld\n", (dp[n][1] + dp[n][0]) % MOD);
    return 0;
}
View Code

Typing practice

思路:KMP

隊友代碼:

#include<bits/stdc++.h>
using namespace std;
long long dp[1010][2];
int nnxt[5][100010];
int ans[100010];
void init(int MIN){
    for(int i=0;i<=100010;i++)ans[i]=MIN;
}
void getNext(string ptr, int next[]){
    next[0] = -1;
    int j = 0, k = -1;
    while(j < ptr.size()){
        if (k == -1 || ptr[j] == ptr[k]){
            if (ptr[++j] == ptr[++k])
                next[j] = next[k];
            else next[j] = k;
        } else k = next[k];
    }
}
int I[100010],J[100010];
bool match[100010];
int KMP(string now, string ptr,int next[]){
    string str;
    int cnt = 0;
    int i = 0, j = 0;
    int pos = 0;
    while(pos < now.length()){
        if(now[pos]=='-'){
            if(str.length())str.pop_back();
            i=I[str.length()],j=J[str.length()];
            cnt+=match[str.length()];
            pos++;
            if(match[str.length()])ans[pos]=0;
            else ans[pos]=min(ans[pos],(int)ptr.length()-j);
//          cout<<j<<' ';
            continue;
        }
        else{
            str.push_back(now[pos]);
            match[str.length()]=0;
            while(i < str.size()){
                if (j == -1 || str[i] == ptr[j]){
                    i++, j++;      
                    if (j == ptr.size()){
                        cnt++; j = next[j];
                        match[str.length()]=1;
                        ans[pos+1]=0;
                        //cout<<j<<endl;
                    }
                }
                else j = next[j];
            }
            I[str.length()]=i,J[str.length()]=j;
            pos++;
            ans[pos]=min(ans[pos],(int)ptr.length()-j);
//          cout<<j<<' ';
        }
    }
    return cnt;
}
 
int main(){
    int n;
    string t[5];
    string s;
    int MIN=0x7fffffff;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>t[i];
        getNext(t[i],nnxt[i]);
        MIN=min(MIN,(int)t[i].length());
    }
    init(0x7fffffff);
    cin>>s;
    for(int i=1;i<=n;i++){
//      cout<<"  ";
        KMP(s,t[i],nnxt[i]);
//      cout<<endl;
//
//      cout<<endl;
    }
        cout<<MIN<<endl;
        for(int i=1;i<=s.length();i++)cout<<ans[i]<<endl;   
    return 0;
}
 
View Code

Longest Common Subsequence

Prefix Sum

Juggernaut

Maze

牛客網暑期ACM多校訓練營(第十場)

Rikka with Lowbit

思路:每次修改後這個位置的指望值不變,由於加上一個lowbit和減去一個lowbit後取平均值仍是原來的值。

隊友代碼:

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
long long a[100010];
long long pre[100010];
long long POW(long long x,long long n){
    long long re=1,base=x;
    while(n){
        if(n&1)(re*=base)%=mod;
        (base*=base)%=mod;
        n>>=1;
    }
    return re;
}
int main(){
    int T;
    int n,m;
    int u,v,w;
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%lld",a+i);
        }
        for(int i=1;i<=n;i++){
            pre[i]=(pre[i-1]+a[i])%mod;
        }
        long long pp=POW(2ll,1ll*n*m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            if(u==2){
                printf("%lld\n",((pre[w]-pre[v-1]+mod)%mod)*pp%mod);
            }
        }
    }
    return 0;
}
View Code

Rikka with Burrow-Wheeler Transform

Rikka with Rotate

Rikka with Prefix Sum

思路:推出每一個位置i的k階前綴和的公式∑C(i+k-1, k)*a[j] (1 <= j <= i),而後用差分記錄第一種操做的修改(否則保存不下),將差分當作-1階的前綴和,而後查詢的時候將全部出現過的修改都用公式求一下前綴和查詢到修改之間有幾回第二種操做就是他的階數,記得要加1,由於咱們用差分記錄的。

隊友代碼:

#include<bits/stdc++.h>
using namespace std;
long long fac[200010],inv[200010];
const long long mod=998244353;
int L[200010],R[200010],val[200010],cnt[200010],top,tot;
long long POW(long long x,long long n){
    long long re=1,base=x;
    while(n){
        if(n&1)(re*=base)%=mod;
        (base*=base)%=mod;
        n>>=1;
    }
    return re;
}
long long C(long long n,long long m){
    if(n<0||m<0||n<m)return 0;
    return fac[n]*inv[n-m]%mod*inv[m]%mod;
}
void init(){
    top=0,tot=0;
}
void INIT(){
    fac[0]=1;
    for(int i=1;i<=200001;i++)fac[i]=fac[i-1]*i%mod;
    inv[200001]=POW(fac[200001],mod-2);
    for(int i=200001;i>=1;i--)inv[i-1]=inv[i]*i%mod;
}
int main(){
    INIT();
    int T,n,m,op;
    int l,r,v;
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d",&l,&r,&v);
                L[top]=l,R[top]=r,val[top]=v,cnt[top++]=tot;
            }
            else if(op==2)tot++;
            else{
                long long ans=0;
                scanf("%d%d",&l,&r);
                for(int j=0;j<top;j++){
                        ans+=
                        C(r-L[j]+tot-cnt[j]+1,tot-cnt[j]+1)*val[j]%mod
                        +C(r-R[j]-1+tot-cnt[j]+1,tot-cnt[j]+1)*(-val[j])%mod
                        -C(l-1-L[j]+tot-cnt[j]+1,tot-cnt[j]+1)*val[j]%mod
                        -C(l-1-R[j]-1+tot-cnt[j]+1,tot-cnt[j]+1)*(-val[j])%mod;
                    ((ans%=mod)+=mod)%=mod;
                }
                cout<<ans<<endl;
            }
        }
    }
    return 0;
}
View Code

Rikka with Equation

Rikka with Line Graph

Rikka with Shortest Path

Rikka with Ants

Rikka with Zombies

Rikka with Nickname

思路:記錄下每一個字母的位置,而後合併時查找第一個可行的位置,而後更新可行區間。

隊友代碼:

#include<bits/stdc++.h>
using namespace std;
int idx(char c){
    return c-'a';
}
vector<int> pos[26];
int getPos(int id,int p){
    if(lower_bound(pos[id].begin(),pos[id].end(),p)==pos[id].end())return -1;
    else return pos[id][lower_bound(pos[id].begin(),pos[id].end(),p)-pos[id].begin()];
}
void init(){
    for(int i=0;i<26;i++)pos[i].clear();
}
char ans[1000010];
char s[1000010];
int main(){
    int T,n,m;
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        scanf("%d",&n);
        int tot=0;
        init();
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            m=strlen(s);
            int ppos=0;
            for(int j=0;j<m;j++){
                if(ppos==-1){
                    pos[idx(s[j])].push_back(tot);
                    ans[tot++]=s[j];
                }
                else{
                    ppos=(getPos(idx(s[j]),ppos));
                    if(ppos==-1){
                        pos[idx(s[j])].push_back(tot);
                        ans[tot++]=s[j];
                    }
                    else{
                        ppos++;
                    }
                }
            }
        }
        ans[tot]=0;
        puts(ans);
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索