1. 程式人生 > 實用技巧 >2019ccpc網路賽

2019ccpc網路賽

A題

簡單判斷

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int main(){
    cin>>t;
    while(t--){
        ll x,y;cin>>x>>y;
        ll ts=x&y;
        ll res=0;
        ll ean=0;
        while(x||y){
            
            //0 1 ->0
            //1 1 ->0
if(x&y&1){ ean+=1ll<<res; } x>>=1; y>>=1; res++; } if(ean==0) cout<<1<<endl; else cout<<ean<<endl; } }
View Code

B題

權值線段樹維護答案

#include<bits/stdc++.h>
using
namespace std; typedef long long ll; int t; int main(){ cin>>t; while(t--){ ll x,y;cin>>x>>y; ll ts=x&y; ll res=0; ll ean=0; while(x||y){ //0 1 ->0 //1 1 ->0 if(x&y&1){ ean
+=1ll<<res; } x>>=1; y>>=1; res++; } if(ean==0) cout<<1<<endl; else cout<<ean<<endl; } }
View Code

C題

字尾陣列+二分+主席樹

#include<bits/stdc++.h>
using namespace std;
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,q;
char t[N];
int sa[N],rk[N],od[N],cnt[N],id[N],px[N];
ll h[N];
int root[N];
ll f[N][26];
ll lg[N],idx;
struct node{
    int l,r;
    int cnt;
}tr[40*N];
bool cmp(int x, int y, int w){
  return od[x]==od[y]&&od[x+w]==od[y+w];
}
void build(int &rt,int l,int r){
    rt=++idx;
    tr[rt]={l,r,0};
    if(l==r)
        return;
    int mid=l+r>>1;
    build(tr[rt].l,l,mid);
    build(tr[rt].r,mid+1,r);
}
void da(int n,int m){
    int i;
    memset(cnt,0,sizeof cnt);
    for(i=1;i<=n;i++) cnt[rk[i]=t[i]]++;
    for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
    for(i=n;i>=1;i--) sa[cnt[rk[i]]--]=i;
    int p;
    for(int w=1;w<n;w<<=1,m=p){
        p=0;
        for(i=n;i>n-w;i--)
            id[++p]=i;
        for(i=1;i<=n;i++)
            if(sa[i]>w)
                id[++p]=sa[i]-w;
        memset(cnt,0,sizeof cnt);
        for(i=1;i<=n;i++) cnt[px[i]=rk[id[i]]]++;
        for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
        for(i=n;i>=1;i--) sa[cnt[px[i]]--]=id[i];
        for(i=0;i<=n;i++) od[i]=rk[i];
        for(p=0,i=1;i<=n;i++){
            rk[sa[i]]=cmp(sa[i-1],sa[i],w)?p:++p;
        }
    }
}
void st(int n){
    int i,j;
    for(i=1;i<=n;i++)
        f[i][0]=h[i];
    lg[1]=0;
    for(i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
    for(j=1;j<=lg[n];j++){
        for(i=1;i+(1<<j)-1<=n;i++){
            f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);
        }
    }
}
int query(int l,int r){
    if(l>r)
        swap(l,r);
    l++;
    int len=lg[r-l+1];
    return min(f[l][len],f[r-(1<<len)+1][len]);
}
void get_height(int n){
    int i;
    for(i=1;i<=n;i++){
        if(rk[i]==1)
            continue;
        int a=max(h[rk[i-1]]-1,1ll*0);
        while(i+a<=n&&t[i+a]==t[sa[rk[i]-1]+a])
            a++;
        h[rk[i]]=a;
    }
    st(n);
}
int getL(int l,int r,int len,int x){
    while(l<r){
        int mid=l+r>>1;
        if(query(mid,x)>=len){
            r=mid;
        }
        else{
            l=mid+1;
        }
    }
    return l;
}
int getR(int l,int r,int len,int x){
    while(l<r){
        int mid=l+r+1>>1;
        if(query(mid,x)>=len)
            l=mid;
        else
            r=mid-1;
    }
    return l;
}
int getans(int p,int q,int l,int r,int k){
    if(l==r)
        return l;
    int cnt=tr[tr[q].l].cnt-tr[tr[p].l].cnt;
    int mid=l+r>>1;
    if(k<=cnt)
    return getans(tr[p].l,tr[q].l,l,mid,k);
    else
    return getans(tr[p].r,tr[q].r,mid+1,r,k-cnt);
}
int solve(int l,int r,int k){
    int len=r-l+1;
    int L=getL(1,rk[l],len,rk[l]);
    int R=getR(rk[l],n,len,rk[l]);
    if(k>R-L+1)
        return -1;
    return getans(root[L-1],root[R],1,n,k);
}
void add(int &rt,int l,int r,int p,int pos,int k){
    rt=++idx;tr[rt]=tr[p];
    if(l==r){
        tr[rt].cnt+=k;
        return ;
    }
    int mid=l+r>>1;
    if(pos<=mid) add(tr[rt].l,l,mid,tr[p].l,pos,k);
    else add(tr[rt].r,mid+1,r,tr[p].r,pos,k);
    tr[rt].cnt=tr[tr[rt].l].cnt+tr[tr[rt].r].cnt;
}
int main(){
    //ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&q);
        scanf("%s",t+1);
        int lent=strlen(t+1);
        da(lent,150);
        get_height(lent);
        idx=0;
        build(root[0],1,n);
        for(int i=1;i<=n;i++){
            int pos=sa[i];
            add(root[i],1,n,root[i-1],pos,1);
        }
        while(q--){
            int l,r,k;
            scanf("%d%d%d",&l,&r,&k);
            cout<<solve(l,r,k)<<endl;
        }
    }
}
View Code

D題

貪心+優先佇列

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
struct edge{
    ll to,w;
    bool operator <(const edge& t)const{
        return w<t.w;
    }
};
struct node{
    ll pre,to,num,w;
    bool operator <(const node&t) const{
        return w>t.w;
    }
};
vector<edge> g[N];
int k[N];
ll ans[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n,m,Q;
        cin>>n>>m>>Q;
        int i;
        for(i=1;i<=n;i++) g[i].clear();
        for(i=1;i<=m;i++){
            int a,b,c;
            cin>>a>>b>>c;
            g[a].push_back({b,c});
        }
        priority_queue<node> q;
        int mx=0;
        for(i=1;i<=Q;i++){
            cin>>k[i];
            mx=max(mx,k[i]);
        }
        int cnt=0;
        for(i=1;i<=n;i++){
            sort(g[i].begin(),g[i].end());
            if(g[i].size())
            q.push({i,g[i][0].to,0,g[i][0].w});
        }
        while(q.size()){
            auto t=q.top();
            q.pop();
            cnt++;
            ans[cnt]=t.w;
            if(cnt==mx)
                break;
            if(t.num<(int)g[t.pre].size()-1){
                q.push({t.pre,g[t.pre][t.num+1].to,t.num+1,t.w-g[t.pre][t.num].w+g[t.pre][t.num+1].w});
            }
            if((int)g[t.to].size()){
                q.push({t.to,g[t.to][0].to,0,t.w+g[t.to][0].w});
            }
        }
        for(i=1;i<=Q;i++){
            cout<<ans[k[i]]<<endl;
        }
    }
}
View Code

F題

簽到模擬

#include<bits/stdc++.h>
using namespace std;
using namespace std;
typedef long long ll;
const int N=5e5+10;
int cnt[N];
int st[N];
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int i;
    int n,m;
    cin>>n>>m;
    int id=0;
    for(i=1;i<=n;i++){
        cin>>a[i];
    }
    while(m--){
        int x;
        cin>>x;
        cnt[++id]=x;
    }
    for(i=id;i>=1;i--){
        if(!st[a[cnt[i]]]){
            cout<<a[cnt[i]]<<" ";
            st[a[cnt[i]]]=1;
        }
        else{
            continue;
        }
    }
    for(i=1;i<=n;i++){
        if(!st[a[i]]){
            cout<<a[i]<<" ";
        }
    }
    //cout<<endl;
}
View Code

G題

簽到

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int s[3000][3000];
void change(){
    for(int i=1;i<=1024;i++){
        for(int j=1;j<=1024;j++){
            if(s[i][j]==1){
                s[2*i-1][2*j]=s[2*i-1][2*j-1]=s[2*i][2*j]=1;
                s[2*i][2*j-1]=0;
            }else{
                s[2*i-1][2*j]=s[2*i-1][2*j-1]=s[2*i][2*j]=0;
                s[2*i][2*j-1]=1;
            }
        }
    }
}
int main(){
    s[1][1]=s[1][2]=s[2][2]=1;
    change();
    int t;
    cin>>t;
    while(t--){
        int n;cin>>n;
        for(int i=1;i<=pow(2,n);i++){
            for(int j=1;j<=pow(2,n);j++){
                if(s[i][j]==1)cout<<"C";
                else cout<<"P";
            }
            cout<<endl;
        }
    }
}
View Code

H題

貪心排序

#include<bits/stdc++.h>
using namespace std;
using namespace std;
typedef long long ll;
const int N=5e5+10;
int a[N],b[N];
ll k;
int main(){
    ios::sync_with_stdio(false);
    int n;
    int t;
    cin>>t;
    while(t--){
        cin>>n>>k;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        sort(a+1,a+1+n);
        reverse(a+1,a+1+n);
        ll sum=0;
        ll res=0;
        for(i=1;i<=n;i++){
            b[i]=a[i]%k;
            sum+=a[i]/k;
            res+=a[i];
        }
        ll ans=k;
        if(sum>=n-1){
            cout<<res+k<<endl;
        }
        else{
            sort(b+1,b+1+n);
            reverse(b+1,b+1+n);
            for(i=1;i<=n-1-sum;i++){
                res+=(k-b[i]);
            }
            cout<<res+k<<endl;
        }
    }

}
View Code