2018 Multi-University Training Contest 2

本文提供了三道算法竞赛题目的解答思路与代码实现,包括简单的签到题、构造方案题及涉及线段树和区间更新的复杂问题。通过具体实例展示了如何使用C++进行高效编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D
签到。

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        cout<<"Yes\n";
    }
}

E
手玩一个构造方案出来。发现43不够,就47取左上角。

#include <bits/stdc++.h>
using namespace std;
int n=47;
char g[3002][3002];
int cnt[3002][3002];
int main(){
    int sum=n*n*n;
    for(int i=0;i<2300;i++){
        for(int j=0;j<2300;j++)g[i][j]='0';
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            int tmp=j;
            for(int k=0;k<n;k++){
                if(k!=0)tmp+=i;
                tmp%=n;
                g[k*n+tmp][i*n+j]='1';
            }
        }
    }
    printf("%d\n",2000);
    for(int i=0;i<2000;i++){g[i][2000]=0;printf("%s\n",g[i]);}
}

G
线段树维护区间最大值,支持区间减1。当区间最大值为0的时候说明有数减到0了,暴力单点更新。由于答案是O(nlogn)O(nlogn)的,暴力的次数很少。

#include <bits/stdc++.h>
using namespace std;
const int maxn=100003;
int n,q;
struct BIT{
    int c[100003];
    void init(){
        memset(c,0,sizeof(c));
    }
    int lowbit(int x){
        return x&(-x);
    }
    void update(int x){
        while(x<=100000){
            c[x]++;
            x+=lowbit(x);
        }
    }
    int query(int x){
        int ret=0;
        while(x){
            ret+=c[x];
            x-=lowbit(x);
        }
        return ret;
    }
}bit;
int a[maxn];
int mi[maxn<<2];
int lz[maxn<<2];

inline void pushdown(int u){
    if(lz[u]==0)return;
    lz[2*u]+=lz[u];
    mi[2*u]-=lz[u];
    lz[2*u+1]+=lz[u];
    mi[2*u+1]-=lz[u];
    lz[u]=0;
}

void build(int u,int l,int r){
    lz[u]=0;
    if(l==r){
        mi[u]=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(2*u,l,mid);
    build(2*u+1,mid+1,r);
    mi[u]=min(mi[2*u],mi[2*u+1]);
}

void update(int u,int ql,int qr,int l,int r){
    if(ql>r||qr<l)return;
    if(ql<=l&&r<=qr&&mi[u]>1){
        lz[u]++;
        mi[u]--;
        return;
    }
    if(l==r){
        bit.update(l);
        mi[u]=a[l];
        return;
    }
    int mid=(l+r)/2;
    pushdown(u);
    update(2*u,ql,qr,l,mid);
    update(2*u+1,ql,qr,mid+1,r);
    mi[u]=min(mi[2*u],mi[2*u+1]);
}

int main(){
    while(~scanf("%d%d",&n,&q)){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        bit.init();
        char s[10];
        int l,r;
        for(int i=1;i<=q;i++){
            scanf("%s%d%d",&s,&l,&r);
            if(s[0]=='a')update(1,l,r,1,n);
            else printf("%d\n",bit.query(r)-bit.query(l-1));
        }
    }
}

J
签到。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100003];
int b[100003];
int c[100003];
int lowbit(int x){
    return x&(-x);
}
void update(int x){
    while(x){
        c[x]++;
        x-=lowbit(x);
    }
}
int query(int x){
    int ret=0;
    while(x<=100000){
        ret+=c[x];
        x+=lowbit(x);
    }
    return ret;
}
int main(){
    int n,x,y;
    while(~scanf("%d%d%d",&n,&x,&y)){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        memset(c,0,sizeof(c));
        ll sum=0;
        for(int i=1;i<=n;i++){
            int p=lower_bound(b+1,b+1+n,a[i])-b;
            sum+=query(p+1);
            update(p);
        }
        printf("%lld\n",sum*min(x,y));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值