2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛

Posted kikokiko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛相关的知识,希望对你有一定的参考价值。

[2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛]

(A.^ & ^)

签到,只把AB都有的位给异或掉

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
using LL = int_fast64_t;
int main(){
    LL T,a,b;
    ____();
    cin >> T;
    while(T--){
        cin >> a >> b;
        cout << ((a&b)==0?1:(a&b)) << endl;
    }
    return 0;
}

(B.array)

给出一个排列(1~n各出现一次),有两种操作:
1、把其中一个数加上1e7
2、问区间(1)~(r)中不小于(k)且没有在区间内出现过的最小的数是多少
对于第一种操作,由于(kle n),所以给一个数加上1e7相当于把这个数删了,所以第一个操作相当于删除这个数
对于第二种操作,首先判断区间内存不存在(k),不存在则直接输出(k),如果存在的话,就找区间内从(k)开始的最长连续串,这个可以二分连续串长度,然后先判断其中有点被删除了,没有的话用主席树判断是否所有点都在1~(r)的区间内

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
const int INF = 0x3f3f3f3f;
int T,n,m,A[MAXN],rp[MAXN];
struct BinaryIndexed_Tree{
    int val[MAXN];
    #define lowbit(x) (x&(-x))
    void init(){ memset(val,0,sizeof(val)); }
    void update(int pos){
        while(pos<=n){
            val[pos]++;
            pos += lowbit(pos);
        }
    }
    int query(int pos){
        int res = 0;
        while(pos){
            res += val[pos];
            pos -= lowbit(pos);
        }
        return res;
    }
}BIT;
struct PersistentSegmentTree{
    int tot,sum[MAXN<<5],ls[MAXN<<5],rs[MAXN<<5],root[MAXN];
    void update(int &now, int pre, int L, int R, int pos){
        now = ++tot;
        ls[now] = ls[pre];
        rs[now] = rs[pre];
        sum[now] = sum[pre] + 1;
        if(L+1==R) return;
        int mid = (L+R) >> 1;
        if(pos < mid) update(ls[now],ls[pre],L,mid,pos);
        else update(rs[now],rs[pre],mid,R,pos);
    }
    void build(){
        tot = 0;
        for(int i = 1; i <= n; i++) update(root[i],root[i-1],1,n+1,A[i]);
    }
    int _kth(int lo, int ro, int L, int R, int k){
        if(L+1==R) return L;
        int lsz = sum[ls[ro]] - sum[ls[lo]];
        int mid = (L+R) >> 1;
        if(k<=lsz) return _kth(ls[lo],ls[ro],L,mid,k);
        else return _kth(rs[lo],rs[ro],mid,R,k-lsz);
    }
    int _rk(int lo, int ro, int L, int R, int x){
        if(L+1==R) return 1;
        int mid = (L+R) >> 1;
        if(x<mid) return _rk(ls[lo],ls[ro],L,mid,x);
        else return sum[ls[ro]]-sum[ls[lo]] + _rk(rs[lo],rs[ro],mid,R,x);
    }
    int kth(int L, int R, int k){ return _kth(root[L-1],root[R],1,n+1,k); }
    int rk(int L, int R, int x){ return _rk(root[L-1],root[R],1,n+1,x); }
}PST;
inline int read(){
    int x = 0, f = 1;
    char c = getchar();
    while(c!='-'&&(c<'0'||c>'9')) c = getchar();
    if(c=='-') f = -1,c = getchar();
    while(c>='0'&&c<='9') x = x*10+c-'0', c = getchar();
    return f*x;
}
void work(){
    n = read(), m = read();
    for(int i = 1; i <= n; i++){
        A[i] = read();
        rp[A[i]] = i;
    }
    PST.build();
    BIT.init();
    int lastans = 0;
    for(int i = 1; i <= m; i++){
        int op = read();
        if(op==1){
            int pos = read();
            pos ^= lastans;
            if(rp[A[pos]]!=INF){
                BIT.update(A[pos]);
                rp[A[pos]] = INF;
            }
        }
        else{
            int lim = read(), x = read();
            lim ^= lastans; x ^= lastans;
            if(rp[x]>lim){
                printf("%d
",lastans=x);
                continue;
            }
            int k = PST.rk(1,lim,x);
            int l = 1, r = lim - k + 1;
            while(l<=r){
                int mid = (l+r) >> 1;
                if(BIT.query(x+mid-1)-BIT.query(x-1)>0||PST.kth(1,lim,k+mid-1)!=x+mid-1) r = mid - 1;
                else l = mid + 1;
            }
            printf("%d
",lastans=x+r);
        }
    }
}
int main(){
    for(T = read(); T; T--) work();
    return 0;
}

(C.K-th occurrence)

给出一个字符串,给出(m)次询问,每次询问在字符串中第(k)次出现字串(s_l~s_r)的位置在哪
首先建出后缀数组和(lcp),对于每次询问,首先找到符合答案条件的区间,可以二分+ST表做,然后在区间中找第(k)大即可,根据(sa)数组建主席树

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
const int INF = 0x3f3f3f3f;
int T,rk[MAXN],sa[MAXN],sec[MAXN],n,m,c[MAXN],lcp[MAXN],ST[MAXN][20];
char s[MAXN];
struct PersistentSegmentTree{
    int tot,root[MAXN<<5],sum[MAXN<<5],ls[MAXN<<5],rs[MAXN<<5];
    void insert(int &now, int pre, int L, int R, int pos){
        now = ++tot;
        ls[now] = ls[pre];
        rs[now] = rs[pre];
        sum[now] = sum[pre] + 1;
        if(L+1==R) return;
        int mid = (L+R) >> 1;
        if(pos < mid) insert(ls[now],ls[pre],L,mid,pos);
        else insert(rs[now],rs[pre],mid,R,pos);
    }
    void build(){
        tot = 0;
        for(int i = 1; i <= n; i++) insert(root[i],root[i-1],1,n+1,sa[i]);
    }
    int _query(int lo, int ro , int k, int L, int R){
        if(L+1==R) return L;
        int lsz = sum[ls[ro]] - sum[ls[lo]];
        int mid = (L+R) >> 1;
        if(k<=lsz) return _query(ls[lo],ls[ro],k,L,mid);
        else return _query(rs[lo],rs[ro],k-lsz,mid,R);
    }
    int query(int L, int R, int k){
        return _query(root[L-1],root[R],k,1,n+1);
    }
}PST;
void SA(int M){
    for(int i = 0; i <= M; i++) c[i] = 0;
    for(int i = 1; i <= n; i++) c[rk[i]=s[i]]++;
    for(int i = 1; i <= M; i++) c[i] += c[i-1];
    for(int i = 1; i <= n; i++) sa[c[rk[i]]--] = i;
    for(int k = 1; k <= n; k <<= 1){
        int p = 0;
        for(int i = n - k + 1; i <= n; i++) sec[++p] = i;
        for(int i = 1; i <= n; i++) if(sa[i]>k) sec[++p] = sa[i]-k;
        for(int i = 0 ; i <= M; i++) c[i] = 0;
        for(int i = 1; i <= n; i++) c[rk[sec[i]]]++;
        for(int i = 1; i <= M; i++) c[i] += c[i-1];
        for(int i = n; i >= 1; i--) sa[c[rk[sec[i]]]--] = sec[i];
        p = 1;
        swap(rk,sec);
        rk[sa[1]] = 1;
        for(int i = 2; i <= n; i++) rk[sa[i]] = (sec[sa[i]]==sec[sa[i-1]]&&sec[sa[i]+k]==sec[sa[i-1]+k])?p:++p;
        if(p==n) break;
        M = p;
    }
}
void Getlcp(){
    int k = 0;
    for(int i = 1; i <= n; i++){
        if(k) k--;
        int j = sa[rk[i]-1];
        while(s[i+k]==s[j+k]) k++;
        lcp[rk[i]] = k;
    }
}
void buildST(){
    for(int i = 1; i <= n; i++) ST[i][0] = lcp[i];
    for(int k = 1; (1<<k) <= n; k++){
        for(int i = 1; (i+(1<<k))-1 <= n; i++){
            ST[i][k] = min(ST[i][k-1],ST[i+(1<<(k-1))][k-1]);
        }
    }
}
int qmin(int l, int r){
    if(l>r) return -1;
    int d = log2(r-l+1);
    return min(ST[l][d],ST[r-(1<<d)+1][d]);
}
void work(){
    scanf("%d %d",&n,&m);
    scanf("%s",s+1);
    SA(256);
    Getlcp();
    buildST();
    PST.build();
    while(m--){
        int L, R, k, st, ed;
        scanf("%d %d %d",&L,&R,&k);
        int d = R - L + 1;
        int pos = rk[L];
        int l = 1, r = pos;
        while(l<=r){
            int mid = (l+r) >> 1;
            if(qmin(pos-mid+1,pos)>=d) l = mid + 1;
            else r = mid - 1;
        }
        st = pos - r;
        l = 1, r = n - pos;
        while(l<=r){
            int mid = (l+r) >> 1;
            if(qmin(pos+1,pos+mid)>=d) l = mid + 1;
            else r = mid - 1;
        }
        ed = pos + r;
        if(st+k-1>ed) printf("-1
");
        else printf("%d
",PST.query(st,ed,k));
    }
}
int main(){
    for(scanf("%d",&T);T;T--) work();
    return 0;
}

(D.path)

(E.huntian oy)

(F.Shuffl Card)

给一个序列,每次取出其中一个数放到最前面,问最终序列
只考虑每个最后一次放到前面的数,如果没有被放到前面过就按顺序在最后输出

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n,m,A[MAXN],vis[MAXN],B[MAXN];
int main(){
    while(scanf("%d %d",&n,&m)!=EOF){
        for(int i = 1; i <= n; i++) scanf("%d",&A[i]);
        queue<int> que;
        for(int i = 1; i <= m; i++) scanf("%d",&B[i]);
        for(int i = m; i >= 1; i--){
            if(vis[B[i]]) continue;
            que.push(B[i]);
            vis[B[i]] = true;
        }
        for(int i = 1; i <= n; i++) if(!vis[A[i]]) que.push(A[i]);
        while(!que.empty()){
            printf("%d ",que.front());
            que.pop();
        }
    }
    return 0;
}

(G.Windows Of CCPC)

签到,递归构造即可

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
int t,k;
char s[1111][1111];
void solve(int x, int y, char C, char P, int kk){
    if(kk==1){
        s[x][y] = C;
        s[x][y+1] = C;
        s[x+1][y+1] = C;
        s[x+1][y] = P;
        return;
    }
    int gap = (1<<(kk-1));
    solve(x,y,C,P,kk-1);
    solve(x+gap,y+gap,C,P,kk-1);
    solve(x,y+gap,C,P,kk-1);
    solve(x+gap,y,P,C,kk-1);
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&k);
        memset(s,0,sizeof(s));
        solve(1,1,'C','P',k);
        for(int i = 1; i <= (1<<k); i++) printf("%s
",s[i]+1);
    }
    return 0;
}

(H.Fishing Master)

首先第一次捕??的时间是必须要用上的,然后每次最好利用煮??的时间去捕??,而且回来的时候??还没有煮熟。
如果到最后一定要浪费掉捕??的时间(也就是在捕??的时候,??已经煮熟了),那就要选(%k)余数大的,这样浪费的时间就能更少

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
using LL = int_fast64_t;
int T,n,k,A[MAXN];
void solve(){
    scanf("%d %d",&n,&k);
    LL res = k,s = 0;
    for(int i = 1; i <= n; i++){
        scanf("%d",&A[i]);
        s += A[i]/k;
        res += A[i];
    }
    if(s<n-1){
        sort(A+1,A+1+n,[](const int &x, const int &y){ return x%k > y%k; });
        for(int i = 1; i <= n-1-s; i++) res += k-A[i]%k;
    }
    printf("%I64d
",res);
}
int main(){
    for(scanf("%d",&T); T; T--) solve();
    return 0;
}

(I.Kaguya)

(J.Touma Kazusa's function)

(K.sakura)

以上是关于2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛的主要内容,如果未能解决你的问题,请参考以下文章

2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛

赛后总结+部分题解2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛

2016中国大学生程序设计竞赛(ccpc 杭州)题解报告

2016中国大学生程序设计竞赛(ccpc 杭州)题解报告

2016中国大学生程序设计竞赛(ccpc 长春) Fraction模拟

2016中国大学生程序设计竞赛(ccpc 长春)题解报告