Codeforces Round #791 (Div. 2)(A-C)题解

A. AvtoBus

题目链接:Problem - A - Codeforces

题意:给出总车轮数,有两种车,一种车有四个轮子,一种车有六个轮子。求最小满足的车辆数和最大满足的车辆数。

思路:分类讨论除以4或者6即可。

AC code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
signed main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n;
        if(n<=3 || n&1){
            cout<<-1<<endl;
            continue;
        }
        int x=0,y=0;
        x=n/4;
        y=(n+5)/6;
        cout<<y<<' '<<x<<endl;
    }
    return 0;
}

B. Stone Age Problem

题目链接:Problem - B - Codeforces

题意:给出n个数和q次询问,询问有两种类型,一是给出下标i和值x,使得a[i]=x,二是给出值x,将所有的值都替换成x。求每次询问后的数组总和。

思路:用一个last数组记录下标j上一次被修改的时间,然后再用id和v记录上一次第二种类型询问的时间和值。

AC code:

#include <bits/stdc++.h>

using namespace std;
int n,q,a[200010],last[200010];
int main(){
    cin>>n>>q;
    long long sum=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum+=a[i];
        last[i]=0;
    }
    int id=0,v=0;
    for(int i=1;i<=q;i++){
        int t;
        cin>>t;
        if(t==1){
            int j,x;
            cin>>j>>x;
            if(last[j]<id){
                sum+=(x-v);
            }else{
                sum+=(x-a[j]);
            }
            last[j]=i;
            a[j]=x;
        }else{
            int x;
            cin>>x;
            sum=1ll*x*n;
            id=i;
            v=x;
        }
        cout<<sum<<endl;
    }
    return 0;
}

C. Rooks Defenders

题目链接:Problem - C - Codeforces

题意:给出边长为n的正方形,有q次操作,分为三种类型,第一种类型是添加石头在某一位置,第二种是删除某一位置的石头,第三种是给出两个坐标,问它们形成的矩形中所有的格子是否都被攻击。被攻击 指的是在这一行或者这一列中有石头。石头所在的行和列都会被攻击。

思路:直接暴力遍历肯定超时,用两个树状数组分别维护行和列的石头数量,单点修改,区间查询。若最开始行和列没有石头,则可以进行单点+1,若行和列有石头,则可以进行单点-1,最后check一下行列中满足一个即可。(小萌新看了佬的思路才学的树状数组.....)

AC code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,q,cnt1[100010],cnt2[100010],sum1[100010],sum2[100010];
signed lowbit(int x){
    return x&(-x);
}
signed getsum1(int x){
    int sum=0;
    while(x>0){
        sum+=sum1[x];
        x-=lowbit(x);
    }
    return sum;
}
signed getsum2(int x){
    int sum=0;
    while(x>0){
        sum+=sum2[x];
        x-=lowbit(x);
    }
    return sum;
}
void add1(int x,int k){
    while(x<=n){
        sum1[x]+=k;
        x+=lowbit(x);
    }
}
void add2(int x,int k){
    while(x<=n){
        sum2[x]+=k;
        x+=lowbit(x);
    }
}
signed main(){
    scanf("%lld%lld",&n,&q);
    while(q--){
        int t;
        scanf("%lld",&t);
        if(t==1){
            int x,y;
            scanf("%lld%lld",&x,&y);
            cnt1[x]++;
            cnt2[y]++;
            if(getsum1(x)-getsum1(x-1)==0){
                add1(x,1);
            }
            if(getsum2(y)-getsum2(y-1)==0){
                add2(y,1);
            }
        }else if(t==2){
            int x,y;
            scanf("%lld%lld",&x,&y);
            cnt1[x]--;
            cnt2[y]--;
            if(!cnt1[x]){
                add1(x,-1);
            }
            if(!cnt2[y]){
                add2(y,-1);
            }
        }else if(t==3){
            int x1,x2,y1,y2;
            scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
            if(getsum1(x2)-getsum1(x1-1)==x2-x1+1 || getsum2(y2)-getsum2(y1-1)==y2-y1+1){
                cout<<"Yes"<<endl;
            }else{
                cout<<"No"<<endl;
            }
        }
    }
    return 0;
}

最开始用的cin输入,在test6时就TLE了,改为scanf就AC了.........没话说,看来一些节约时间复杂度的小细节也要注意。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值