Codeforces Round #791 (Div. 2)

Posted on 2022-05-14 21:04  Capterlliar  阅读(25)  评论(0编辑  收藏  举报

A. AvtoBus

题意:有的车有4个轮子,有的车有6个轮子。现在给你轮子的数目,求最大和最小车的数目。

解:首先奇数不行。最少肯定除6,余0刚好,余2减一辆六轮车换两辆4轮车,余4刚好一辆四轮车,都是n/6+1;最多肯定除4,余0刚好,余2减一辆四轮车换六轮,还是n/4。哦判一下小于4的情况。

B. Stone Age Problem

题意:给出数组a和两种操作,操作1是单点修改,操作2是全部变x。求每次操作后数组所有数的和。

解:因为操作2是全部变x嘛,就不用线段树了,每次记录一下这是第几轮全覆盖,单点修改时看当前位置的轮数和总轮数相不相等,来判断是当前值还是之前覆盖值。然后处理sum。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define mod 1000000007
int n,m,q;
ll a[maxx]={0};
int vis[maxx]={0};
signed main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    ll sum=0;
    for(int i=1;i<=n;i++)
        sum+=a[i];
    int cnt=1;
    ll now=0;
    while(q--){
        int t;
        scanf("%d",&t);
        if(t==1){
            ll i,x;
            scanf("%lld%lld",&i,&x);
            if(now==0){
                sum=sum+x-a[i];
            }
            else{
                if(vis[i]==cnt){
                    sum=sum+x-a[i];
                }
                else{
                    sum=sum+x-now;
                }
            }
            vis[i]=cnt;
            a[i]=x;
            printf("%lld\n",sum);
        }
        else if(t==2){
            ll x;
            scanf("%lld",&x);
            sum=n*x;
            printf("%lld\n",sum);
            cnt++;
            now=x;
        }
    }
    return 0;
}
View Code

C. Rooks Defenders

题意:给出一个棋盘,每个棋子会被同行或同列的棋子恰掉。现在圈出一片长方形区域,问这片长方形区域内任意放一个棋子,是否都会被恰掉。

解:啊又是读错题的一天,看成这个区域内是否存在棋子,想了半天动态二维偏序1e5这能做吗,这个故事告诉我们不看样例是不好的。。。正确的题意分析一下就是x1-x2,或y1-y2,至少有一个是每行(列)都有棋子的。没想出啥好办法,写了个线段树。注意开个vis数组,不要重复加减。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define mod 1000000007
int n,m,q;
int tx[maxx*4]={0},ty[maxx*4]={0};
int visx[maxx]={0},visy[maxx]={0};
void insertx(int now,int l,int r,int x,int val){
    if(l==r){
        tx[now]=val;
        return;
    }
    int mid=(l+r)/2;
    if(x<=mid)
        insertx(now*2,l,mid,x,val);
    else
        insertx(now*2+1,mid+1,r,x,val);
    tx[now]=tx[now*2]+tx[now*2+1];
}
void inserty(int now,int l,int r,int x,int val){
    if(l==r){
        ty[now]=val;
        return;
    }
    int mid=(l+r)/2;
    if(x<=mid)
        inserty(now*2,l,mid,x,val);
    else
        inserty(now*2+1,mid+1,r,x,val);
    ty[now]=ty[now*2]+ty[now*2+1];
}
int queryx(int now,int l,int r,int s,int e){
    if(s<=l&&r<=e){
        return tx[now];
    }
    int mid=(l+r)/2;
    int res=0;
    if(s<=mid)
        res+= queryx(now*2,l,mid,s,e);
    if(mid<e)
        res+= queryx(now*2+1,mid+1,r,s,e);
    return res;
}
int queryy(int now,int l,int r,int s,int e){
    if(s<=l&&r<=e){
        return ty[now];
    }
    int mid=(l+r)/2;
    int res=0;
    if(s<=mid)
        res+= queryy(now*2,l,mid,s,e);
    if(mid<e)
        res+= queryy(now*2+1,mid+1,r,s,e);
    return res;
}
signed main(){
    scanf("%d%d",&n,&q);
    while(q--){
        int opt;
        scanf("%d",&opt);
        if(opt==1){
            int x,y;
            scanf("%d%d",&x,&y);
            if(!visx[x])
                insertx(1,1,n,x,1);
            if(!visy[y])
                inserty(1,1,n,y,1);
            visx[x]++;visy[y]++;
        }
        else if(opt==2){
            int x,y;
            scanf("%d%d",&x,&y);
            visx[x]--;visy[y]--;
            if(!visx[x])
                insertx(1,1,n,x,0);
            if(!visy[y])
                inserty(1,1,n,y,0);
        }
        else if(opt==3){
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            int t1= queryx(1,1,n,x1,x2);
            int t2= queryy(1,1,n,y1,y2);
            if(t1==x2-x1+1||t2==y2-y1+1)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}
View Code