Educational Codeforces Round 76 (Rated for Div. 2)

(一场下紫,我是真的nb)

$A$:

送分题。

#include<bits/stdc++.h>
#define maxn 100005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl
 
using namespace std;
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
 
int main(){
    int T=read();
    while(T--){
        int n=read(),x=read(),a=read(),b=read();
        if(a>b) swap(a,b);
        if(x<=a-1+n-b) printf("%d\n",b-a+x);
        else printf("%d\n",n-1);
    }
    return 0;
}
A

 

$B$:

送分题。

#include<bits/stdc++.h>
#define maxn 100005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl
 
using namespace std;
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
 
int main(){
    int T=read();
    while(T--){
        int x=read(),y=read();
        if(y<=x) printf("YES\n");
        else{
            if(x<=3 && y<=3 && x>=2) printf("YES\n");
            else if(x<=3) printf("NO\n");
            else printf("YES\n");
        } 
    }
    return 0;
}
B

 

$C$:

题意是请你找出一个最短的区间满足其中有某个元素出现次数大于其他所有元素的出现次数。

然后有个结论:答案就是最近的两个相同字符构成的区间。显然可以反证。

看出来了就是看出来了,没看出来就是直接去世,比如说我。

#include<bits/stdc++.h>
#define maxn 200005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl
 
using namespace std;
int a[maxn];
vector<int> ind[maxn]; 
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
 
int main(){
    int T=read();
    while(T--){
        int n=read();
        for(int i=1;i<=n;i++) ind[i].clear();
        for(int i=1;i<=n;i++) a[i]=read(),ind[a[i]].push_back(i);
        int ans=inf;
        for(int i=1;i<=n;i++){
            if(ind[i].size()==0) continue;
            for(int j=0;j<ind[i].size()-1;j++)
                ans=min(ans,ind[i][j+1]-ind[i][j]+1);
        }
        if(ans==inf) printf("%d\n",-1);
        else printf("%d\n",ans);
    }
    return 0;
}
C

 

$D$:

送分题,但我挂在了一个普及组都不会挂的地方:

单点修改和单点更新最值是不一样的。

if(l==r){mx[k]=v;return;}
if(l==r){mx[k]=max(mx[k],v);return;}

这两段话的区别我调了半个小时都没调出来,我不退役谁退役?

#include<bits/stdc++.h>
#define maxn 400005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl
 
using namespace std;
int n,m,a[maxn],pp[maxn],po[maxn],s[maxn];
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
 
struct node{
    int mx[maxn<<2];
    inline void upd(int l,int r,int p,int v,int k){
        if(l==r){if(v==0)mx[k]=v;else mx[k]=max(mx[k],v);return;}
        int mid=l+r>>1;
        if(p<=mid) upd(l,mid,p,v,k<<1);
        else upd(mid+1,r,p,v,k<<1|1);
        mx[k]=max(mx[k<<1],mx[k<<1|1]);
        return;
    }
    inline int query(int l,int r,int x,int y,int k){
        if(x<=l && r<=y) return mx[k];
        int mid=l+r>>1,res=0;
        if(x<=mid) res=max(res,query(l,mid,x,y,k<<1));
        if(y>mid) res=max(res,query(mid+1,r,x,y,k<<1|1));
        return res;
    }
}t1,t2;
 
inline bool check(int x,int y){
    int tp=t1.query(1,n+m,x,y,1);
    if(t2.query(1,n+m,tp,n+m,1)>=y-x+1) return 1;
    else return 0;
}
 
int main(){
    int T=read();
    while(T--){
        n=read(); for(int i=1;i<=n;i++) a[i]=read(),pp[i]=a[i];
        m=read(); for(int i=1;i<=m;i++) po[i]=read(),pp[i+n]=po[i],s[i]=read();
        sort(pp+1,pp+1+n+m);
        for(int i=1;i<=n;i++) a[i]=lower_bound(pp+1,pp+1+n+m,a[i])-pp,t1.upd(1,n+m,i,a[i],1);
        for(int i=1;i<=m;i++) po[i]=lower_bound(pp+1,pp+1+n+m,po[i])-pp,t2.upd(1,n+m,po[i],s[i],1);
        bool flag=0; int num=0;
        for(int i=1;i<=n;){
            int l=1,r=n-i+1,ans=-1;
            while(l<=r){
                int mid=l+r>>1;
                if(check(i,i+mid-1)) ans=mid,l=mid+1;
                else r=mid-1;
            }
            //debug(ans);
            if(ans==-1){flag=1;break;}
            i+=ans,num++;
        }
        if(flag) printf("%d\n",-1);
        else printf("%d\n",num);
        for(int i=1;i<=n;i++) t1.upd(1,n+m,i,0,1);
        for(int i=1;i<=m;i++) t2.upd(1,n+m,po[i],0,1);
    }
    return 0;
}
D

 

$E$:

送分题,直接枚举$1-n$考虑分组即可。

题面太长没看懂,我不退役谁退役?

#include<bits/stdc++.h>
#define maxn 200005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl
 
using namespace std;
int a[maxn],dp[maxn][3];
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
 
int main(){
    int k1=read(),k2=read(),k3=read(),n=k1+k2+k3;
    for(int i=1;i<=k1;i++) a[read()]=0;
    for(int i=1;i<=k2;i++) a[read()]=1;
    for(int i=1;i<=k3;i++) a[read()]=2;
    for(int i=1;i<=n;i++){
        dp[i][0]=(a[i]==0)?(dp[i-1][0]):(dp[i-1][0]+1);
        dp[i][1]=(a[i]==1)?(min(dp[i-1][0],dp[i-1][1])):(min(dp[i-1][0],dp[i-1][1])+1);
        dp[i][2]=(a[i]==2)?(min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))):(min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1);
    }
    printf("%d\n",min(dp[n][0],min(dp[n][1],dp[n][2])));
    return 0;
}
E

 

$F$:

如果你同时知道$meet\space in\space the\space middle$和

map<vector<int>,int>

那么这是送分题。

如果你不知道,比如我,那么废了。

#include<bits/stdc++.h>
#define maxn 105
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl
 
using namespace std;
int a[maxn];
map<vector<int>,int> mp;
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
 
inline int calc(int x){
    int num=0;
    for(int i=29;i>=0;i--)
        if(x>>i&1) num++;
    return num;
}
 
int main(){
    int n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=0;i<(1<<15);i++){
        int tp=calc(i^(a[1]&((1<<15)-1)));
        vector<int> ttp;
        for(int j=2;j<=n;j++)
            ttp.push_back(calc(i^(a[j]&((1<<15)-1)))-tp);
        if(ttp.size()) mp[ttp]=i;
    }
    for(int i=0;i<(1<<15);i++){
        int tp=calc(i^(a[1]>>15));
        vector<int> ttp;
        for(int j=2;j<=n;j++)
            ttp.push_back(tp-calc(i^(a[j]>>15)));
        if(mp[ttp]){printf("%d\n",(i<<15)+mp[ttp]);return 0;}
    }
    printf("-1\n");
    return 0;
}
F

 

$G$:

不会。

 

posted @ 2019-11-14 11:07  Fugtemypt  阅读(99)  评论(0编辑  收藏  举报