2017 ACM/ICPC Asia Regional Shenyang Online - 做題記錄

Spike Valentine發表於2020-11-22

2017 ACM/ICPC Asia Regional Shenyang Online

1.string string string

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 8;
int sa[MAXN], height[MAXN];
int _rank[MAXN], t1[MAXN], t2[MAXN], c[MAXN];
string s;
inline void get_sa(const int &n, int m)
{
    int i, k, *x = t1, *y = t2, p, j;
    for(i = 0; i < m; i++) c[i] = 0;
    for(i = 0; i < n; i++) ++ c[x[i] = s[i]];
    for(i = 1; i < m; i++) c[i] += c[i - 1];
    for(i = n - 1; i >= 0; i--) sa[-- c[x[i]]] = i;
    for(k = 1; k <= n; k <<= 1){
        p = 0;
        for(i = n - k; i < n; i++) y[p ++] = i;
        for(i = 0; i < n; i++) if(sa[i] >= k) y[p ++] = sa[i] - k;
        for(i = 0; i < m; i++) c[i] = 0;
        for(i = 0; i < n; i++) ++ c[x[y[i]]];
        for(i = 1; i < m; i++) c[i] += c[i - 1];
        for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
        swap(x, y), p = 1, x[sa[0]] = 0;
        for(i = 1; i < n; i++)
            x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]) ? p - 1 : p ++;
        if(p >= n) break;
        m = p;
    }
    k = 0;
    for(i = 0; i < n; i++) _rank[sa[i]] = i;
    for(i = 0; i < n; i++){
        if(k) --k; if(!_rank[i]) continue;
        j = sa[_rank[i] - 1];
        while(s[i + k] == s[j + k]) k++;
        height[_rank[i]] = k;
    }
}

inline void print(const int &n)
{
    for(int i = 1; i <= n; i++){
        cout << i << " : " << _rank[sa[i]] << " " << sa[i] << endl;
        for(int j = sa[i]; j < n; j++){
            cout << s[j];
        }
        cout << endl;
    }
    cout << endl;
}

struct ST_list{
    int stTable[MAXN][32], preLog2[MAXN];
    void init(int n){
        preLog2[1] = 0;
        for(int i = 2; i <= n; i++){
            preLog2[i] = preLog2[i-1];
            if((1 << (preLog2[i] + 1)) == i){
                preLog2[i]++;
            }
        }
    }
    void st_prepare(int n, int arr[]){
        for(int i = n - 1; i >= 0; i--){
            stTable[i][0] = arr[i];
            for(int j = 1; (i + (1 << j) - 1) < n; j++){
                stTable[i][j] = min(stTable[i][j - 1], stTable[i + (1 << j - 1)][j - 1]); //1
            }
        }
    }
    int query_min(int l, int r){
        int len = r - l + 1, k = preLog2[len];
        return min(stTable[l][k], stTable[r - (1 << k) + 1][k]);  //2
    }
}st;

int main()
{
    #ifdef LOCAL
    freopen("a.txt", "r", stdin);
    //freopen("a.out", "w", stdout);
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);

    int T, n, i, k;
    LL ans;
    st.init(1e5+2);
    cin >> T;
    while(T--){
        cin >> k;
        cin >> s;

        n = s.size(); height[n+1] = 0;
        get_sa(n+1, 256); st.st_prepare(n+2, height);
        //使用st表示要訪問n+1,由於0~n-1based 所以陣列的大小為n+2,不然height[n+1] = 0這個數不會進入st表
        //print(n);
        ans = 0;
        if(k >= 2){
            for(i = k; i <= n; i++){
                ans += st.query_min(i - k + 2, i) - max(st.query_min(i - k + 2, i+1), st.query_min(i - k + 2 - 1, i));
            }
        }
        else{
            for(i = 1; i <= n; i++){
                ans += (n - sa[i]) - max(height[i], height[i+1]);
            }
        }
        cout << ans << "\n";
    }
    return 0;
}

2.cable cable cable

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
#define _for(i,a,b) for(ll i = (a);i < (b); ++i)
#define sc scanf
#define pr printf
#define TLE ios::sync_with_stdio(false); cin.tie(0);
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;

int main() {
    ll m,k;
    while(~sc("%lld %lld",&m,&k)) {
        ll ans = k + (m - k) * k;
        pr("%lld\n",ans);
    }
}

3.happy happy happy

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <ctime>
#define ll long long
#define _for(i,a,b) for(ll i = (a);i < (b); ++i)
#define sc scanf
#define pr printf
#define TLE ios::sync_with_stdio(false); cin.tie(0);
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;

int n,a[maxn]={0},Ma[105][105] = {0},Mi[105][105] = {0};
int st, LIM=1*CLOCKS_PER_SEC;
int ans = INF;

inline void Init() {
    for(int i = 1; i <= n+1; ++i) {
        for(int j = 1; j <= n+1; ++j) {
            Ma[i][j] = -INF;
            Mi[i][j] = INF;
        }
    }
    for(int i = 1; i <= n+1; ++i) {
        Ma[i][i-1] = Mi[i][i-1] = 0;
    }
    for(int l = n; l >= 1; --l) {
        for(int r = l; r <= n; ++r) {
            int L = l, R = r, son = 0;
            if(a[L] >= a[R]) {
                son = a[L];
                ++L;
            }
            else {
                son = a[R];
                --R;
            }
            Ma[l][r] = max(Ma[l][r],
            max((Ma[L+1][R] - a[L] + son),(Ma[L][R-1] - a[R] + son)));
            Mi[l][r] = min(Mi[l][r],
            min((Mi[L+1][R] - a[L] +son),(Mi[L][R-1] - a[R] + son)));
        }
    }
}

void dfs(int l, int r, int dif) {
    //pr("ans: %d\n",ans);
    if(l > r) {
        ans = min(ans,dif);
        return;
    }
    if(dif + Ma[l][r] <= 0)
        return;
    if(dif + Mi[l][r] >= ans)
        return;
    if(dif + Mi[l][r] > 0) {
        ans = min(ans,dif + Ma[l][r]);
        return;
    }
    int son;
    if(a[l] >= a[r]) {
        son = a[l];
        ++l;
    }
    else {
        son = a[r];
        --r;
    }
    if(clock() - st > LIM) return;
    dfs(l + 1, r, dif - a[l] + son);
    dfs(l, r - 1, dif - a[r] + son);
}

int main() {
    while(~sc("%d",&n)) {
        ans = INF;
        _for(i,1,n+1) {
            sc("%d",&a[i]);
        }
        Init();
        st = clock();
        dfs(1,n,0);
        if(ans == INF)
            puts("The child will be unhappy...");
        else printf("%d\n", ans);
    }
}

4.array array array

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
#define _for(i,a,b) for(ll i = (a);i < (b); ++i)
#define sc scanf
#define pr printf
#define TLE ios::sync_with_stdio(false); cin.tie(0);
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;
int a[maxn],dp[maxn];
int n,k;
int main() {
    int t; sc("%d",&t);
    while(t--) {
        sc("%d %d",&n,&k);
        _for(i,0,n) sc("%d",&a[i]);
        dp[0] = a[0];
        int j = 1;
        _for(i,1,n) {
            if(a[i] > dp[j - 1])
                dp[j++] = a[i];
            else {
                int h = lower_bound(dp,dp+j,a[i]) - dp;
                dp[h] = a[i];
            }
        }
        //_for(i,0,n)
        //pr("dp: %d a: %d\n",dp[i],a[i]);
        if(j+k>=n) {
            cout<<"A is a magic array."<<endl; continue;
        }
        dp[0]=a[n-1];
        j=1;
        for(int i=n-2;i>=0;i--) {
            if(a[i]>dp[j-1])
                dp[j++]=a[i];
            else {
                int h=lower_bound(dp,dp+j,a[i])-dp;
                dp[h]=a[i];
            }
        }
        //_for(i,0,n)
        //pr("dp: %d a: %d\n",dp[i],a[i]);
        if(j+k>=n) {
            cout<<"A is a magic array."<<endl; continue;
        }
        cout<<"A is not a magic array."<<endl;
    }
    return 0;
}

5.number number number

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
#define _for(i,a,b) for(ll i = (a);i < (b); ++i)
#define sc scanf
#define pr printf
#define TLE ios::sync_with_stdio(false); cin.tie(0);
const int maxn = 1e8 + 5;
const int INF = 0x3f3f3f3f;
const int mod=998244353;
using namespace std;
ll a[2][2] = {0,1,0,0},b[2][2] = {0,1,1,1},ans[2][2] = {1,0,0,1};
ll k;

inline void Init() {
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(ans,0,sizeof(ans));
    a[0][1] = 1;
    b[0][1] = b[1][0] = b[1][1] = 1;
    ans[0][0] = ans[1][1] = 1;
}

inline void mul(ll ans[][2], ll a[][2], ll b[][2]) {
    ll tmp[2][2] = {0};
    _for(i,0,2) {
        _for(j,0,2) {
            _for(k,0,2) {
                tmp[i][j] = (tmp[i][j] + a[i][k] * b[k][j]) % mod;
            }
        }
    }
    _for(i,0,2) {
        _for(j,0,2) {
            ans[i][j] = tmp[i][j];
        }
    }
}

int main() {
    while(sc("%lld",&k) != EOF) {
        Init();
        ll n = k * 2 + 3;
        while (n) {
            if (n & 1)  mul(ans,ans,b);
            mul(b,b,b);
            n >>= 1;
        }
        mul(ans , a, ans);
        pr("%lld\n",ans[0][0]-1);
    }
}

6.gems gems gems

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define ll long long
#define _for(i,a,b) for(int i = (a);i < (b); ++i)
#define sc scanf
#define pr printf
#define TLE ios::sync_with_stdio(false); cin.tie(0);
const int maxn = 1e3 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;

int Alice[maxn][maxn],Bob[maxn][maxn];
int T,sum[50000],n,t;

inline void Init() {
    memset(Alice,0,sizeof(Alice));
    memset(Bob,0,sizeof(Bob));
}

int main() {
    sc("%d",&T);
    while(T--) {
        Init();
        sc("%d",&n);
        sum[0] = 0;
        _for(i,1,n+1) {
            sc("%d",&t);
            sum[i] = sum[i-1] + t;
        }
        //Alice[i][k] 從第i個開始選,至少選k個的最大差值
        //Bob[i][k] 從第i個開始選,至少選k個的最小差值
        int maxk = (int)sqrt(2 * n) + 1;
        for(int i = n; i >= 1; --i) {
            for(int k = 1; k <= maxk; ++k) {
                if(i + k - 1 > n) break;
                else {
                    Alice[i&255][k] = max(Bob[(i+k)&255][k] + (sum[i+k-1]-sum[i-1]),
                                      i + k <= n ? Bob[(i+k+1)&255][k+1] + (sum[i+k]-sum[i-1]):-INF);
                    Bob[i&255][k] = min(Alice[(i+k)&255][k]-(sum[i+k-1]-sum[i-1]),
                                    i + k <= n ? Alice[(i+k+1)&255][k+1]-(sum[i+k]-sum[i-1]):INF);
                }
            }
        }
        pr("%d\n",Alice[1][1]);
    }
    return 0;
}

相關文章