zoukankan      html  css  js  c++  java
  • 2018暑假多校(杭电 + 牛客)

    天坑。。。

    杭电

    dls代码:https://ideone.com/Wo55gi

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

    2018 Multi-University Training Contest 1

    1001 Maximum Multiple

    打表找规律,发现只有当n是3倍数或者4倍数时才有解

    而且当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。

    正解是解不定方程组

    #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
    ", 1LL * n * n * n / 27);
            else if(n % 4 == 0)printf("%lld
    ", 1LL * n * n * n / 32);
            else printf("-1
    ");
        }
        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
    ", 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);
                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
    ", 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
    ", 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], " 
    "[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("
    ");
        }
        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
    ", 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
    ", 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, " 
    "[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
    ", 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
    ", 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
    ", 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
    ");
            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
    ", (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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ");
            else printf("%d
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", ((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
    ", 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
    ", 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
    ", 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
    ", 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*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
    ", 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
    ",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
    ", 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
    ",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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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], " 
    "[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
    ", dp[n][st]);
        }
        else {
            for (int i = 0; i < (1<<n); i++) t[n][i] = s[i] == '1';
            dfs(n-1);
            printf("%d
    ", 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
    ", 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
    ", i, j);
        }
        for (int i = 1; i <= a; i++) printf("%d %d
    ", i, t+1);
        for (int i = 1; i <= b; i++) printf("%d %d
    ", i, t+2);
        for (int i = 1; i <= c; i++) printf("%d %d
    ", i, t+3);
        for (int i = 1; i <= d; i++) printf("%d %d
    ", i, t+4);
        for (int i = 1; i <= e; i++) printf("%d %d
    ", 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
    ", 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
    ", 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
    ",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
    ", (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
    ",((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
  • 相关阅读:
    上周热点回顾(12.1312.19)
    上周热点回顾(12.612.12)
    上周热点回顾(11.1511.21)
    上周热点回顾(11.2211.28)
    上周热点回顾(11.2912.5)
    [转]ITIL知识体系简介
    [书目20211113]Python自动化测试入门与进阶实战
    [转]敏捷宣言的内容及准则
    [书目20211212]IT运维之道
    python做量化交易干货分享
  • 原文地址:https://www.cnblogs.com/widsom/p/9416058.html
Copyright © 2011-2022 走看看