首页 > 其他分享 >AtCoder Beginner Contest 367 补题记录(A~F)

AtCoder Beginner Contest 367 补题记录(A~F)

时间:2024-08-17 22:04:50浏览次数:9  
标签:AtCoder Beginner f1 int cin pop back 补题 &&

很 Easy 一场,共计用时 \(34\) min

A

const int N=1000100;

signed main(){
    string s;cin>>s;
    int cnt=0;
    int n=s.size();
    if(s[n-1]=='0'&&s[n-2]=='0'&&s[n-3]=='0'){
        s.pop_back();
        s.pop_back();
        s.pop_back();
        s.pop_back();
    }else{
        while(s.back()=='0')
            s.pop_back();
    }
    cout<<s<<'\n';
}

B

signed main(){
    string s;cin>>s;
    int cnt=0;
    int n=s.size();
    if(s[n-1]=='0'&&s[n-2]=='0'&&s[n-3]=='0'){
        s.pop_back();
        s.pop_back();
        s.pop_back();
        s.pop_back();
    }else{
        while(s.back()=='0')
            s.pop_back();
    }
    cout<<s<<'\n';
}

C

发现数的范围很小,所以直接 dfs 然后判断是否合法即可。

const int N=1000100;
int a[N],b[N],n,k;
void dfs(int dep){
    if(dep==n+1){
        int s=0;
        F(i,1,n)s+=b[i];
        if(s%k==0){
            F(i,1,n)cout<<b[i]<<' ';
            cout<<'\n';
        }
        return;
    }
    F(i,1,a[dep]){
        b[dep]=i;
        dfs(dep+1);
    }
}

signed main(){
    cin>>n>>k;
    F(i,1,n)cin>>a[i];
    dfs(1);
}

D

考虑经典套路破换成链,然后双指针扫描合法区间,即求在合法区间内和在模 \(M\) 意义下同余 \(0\) 的方案数。记录每一个前缀和出现次数即可。时间复杂度为 \(O(n)\) 但是我写丑了所以是 \(O(n\log n)\) 的。

const int N=1000100;
int a[N],s[N];
signed main(){
    int n,m;cin>>n>>m;
    F(i,1,n)cin>>a[i];
    F(i,1,n-1)a[i+n]=a[i];
    F(i,1,n+n-1)s[i]=(s[i-1]+a[i])%m;
    map<int,int>mp;
    int cnt=0;
    F(i,1,n+n-1){
        if(i>n)--mp[s[i-n]];
        cnt+=(mp[s[i]]);
        if(i<=n)++mp[s[i]];
        // cout<<i<<": "<<s[i]<<' '<<mp[s[i]]-1<<'\n';
    }
    cout<<cnt<<'\n';
}

E

经典套路,将每一个点分开考虑。设 \(f_{i,x}\) 表示 \(x\) 点连续执行 \(2^i\) 次操作之后到达的点,因此 \(O(\log n)\) 时间复杂度内暴力跳得每一个点的答案即可。时间复杂度为 \(O(n\log n)\)。注意数组不要开小要不然会像我一样调 15min。

const int N=200100;
int x[N],a[N],f[63][N],b[N];
int get(int x,int y){
    int t=x;
    F(i,0,62)
        if(y>>i&1)
            x=f[i][x];
    return x;
}
signed main(){
    int n,k;cin>>n>>k;
    F(i,1,n)cin>>x[i];
    F(i,1,n)cin>>a[i];
    if(k==0){
        F(i,1,n)cout<<a[i]<<' ';
        cout<<'\n';
        return 0;
    }
    F(i,1,n)f[0][i]=x[i];
    F(i,1,62)
        F(j,1,n)f[i][j]=f[i-1][f[i-1][j]];
    F(i,1,n)
        cout<<a[get(i,k)]<<' ';
    cout<<'\n';
}

F

参见原神数学测试本上第 \(35\) 页的 DS 第 \(11\) 题

考虑给两个序列都做一个和位置无关的哈希,然后建两棵线段树,计算其哈希值是否全都一样即可。时间复杂度为 \(O(n\log n)\)。

因为这一类哈希的冲突概率极大,因此考虑多写几个哈希,或者给每一个值随机赋权即可。

const int N=1000100;
int a[N],b[N];
namespace _1{

using ull=unsigned long long;
const int m1=998244353,m2=1e9+7;
struct qwq{
    int l,r,sum,xr,s4m1,s4m2;
    ull s2,s3;
    void init(int p){
        l=r=p;
        sum=xr=a[p];
        s2=a[p]*a[p];
        s3=a[p]*a[p]*a[p];
        s4m1=a[p]*a[p]%m1*a[p]%m1*a[p]%m1;
        s4m2=a[p]*a[p]%m2*a[p]%m2*a[p]%m2;
    }
}z[N<<2];
qwq operator+(const qwq&l,const qwq &r){
    return {l.l,r.r,l.sum+r.sum,l.xr^r.xr,(l.s4m1+r.s4m1)%m1,(l.s4m2+r.s4m2)%m2,l.s2+r.s2,l.s3+r.s3};
}
void build(int l,int r,int rt){
    if(l==r)return z[rt].init(l);
    int mid=l+r>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    z[rt]=z[rt<<1]+z[rt<<1|1];
}
qwq qu(int l,int r,int rt,int ll,int rr){
    if(ll<=l&&r<=rr)return z[rt];
    int mid=l+r>>1;
    if(ll<=mid&&mid<rr)return qu(l,mid,rt<<1,ll,rr)+qu(mid+1,r,rt<<1|1,ll,rr);
    if(ll<=mid)return qu(l,mid,rt<<1,ll,rr);
    return qu(mid+1,r,rt<<1|1,ll,rr);
}
}
namespace _2{

using ull=unsigned long long;
const int m1=998244353,m2=1e9+7;
struct qwq{
    int l,r,sum,xr,s4m1,s4m2;
    ull s2,s3;
    void init(int p){
        l=r=p;
        sum=xr=b[p];
        s2=b[p]*b[p];
        s3=b[p]*b[p]*b[p];
        s4m1=b[p]*b[p]%m1*b[p]%m1*b[p]%m1;
        s4m2=b[p]*b[p]%m2*b[p]%m2*b[p]%m2;
    }
}z[N<<2];
qwq operator+(const qwq&l,const qwq &r){
    return {l.l,r.r,l.sum+r.sum,l.xr^r.xr,(l.s4m1+r.s4m1)%m1,(l.s4m2+r.s4m2)%m2,l.s2+r.s2,l.s3+r.s3};
}
void build(int l,int r,int rt){
    if(l==r)return z[rt].init(l);
    int mid=l+r>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    z[rt]=z[rt<<1]+z[rt<<1|1];
}
qwq qu(int l,int r,int rt,int ll,int rr){
    if(ll<=l&&r<=rr)return z[rt];
    int mid=l+r>>1;
    if(ll<=mid&&mid<rr)return qu(l,mid,rt<<1,ll,rr)+qu(mid+1,r,rt<<1|1,ll,rr);
    if(ll<=mid)return qu(l,mid,rt<<1,ll,rr);
    return qu(mid+1,r,rt<<1|1,ll,rr);
}
}
signed main(){
    int n,q;cin>>n>>q;
    F(i,1,n)cin>>a[i];
    F(i,1,n)cin>>b[i];
    _1::build(1,n,1);
    _2::build(1,n,1);
    while(q--){
        int l,r,ll,rr;
        cin>>l>>r>>ll>>rr;
        if(r-l+1==rr-ll+1){
            auto f1=_1::qu(1,n,1,l,r);
            auto f2=_2::qu(1,n,1,ll,rr);
            if(f1.sum==f2.sum&&f1.xr==f2.xr&&f1.s2==f2.s2&&f1.s3==f2.s3&&f1.s4m1==f2.s4m1&&f1.s4m2==f2.s4m2)cout<<"Yes\n";
            else cout<<"No\n";
        }else cout<<"No\n";
    }
}

标签:AtCoder,Beginner,f1,int,cin,pop,back,补题,&&
From: https://www.cnblogs.com/yhbqwq/p/18365070

相关文章

  • AtCoder Beginner Contest 367
    喜欢我\(\log_210^{18}=18\)吗?A#include<bits/stdc++.h>#defineebemplace_back#defineepemplaceusingnamespacestd;usingll=longlong;inta,b,c;intmain(){ cin.tie(0)->sync_with_stdio(0); cin>>a>>b>>......
  • 题解:AtCoder Beginner Contest 367
    总体情况A题意在AtCoder王国,居民们每天都要在\(A\)点大声喊出他们对章鱼烧的热爱。住在AtCoder王国的高桥每天\(B\)点睡觉,\(C\)点起床(\(24\)小时钟)。他醒着的时候可以喊出对章鱼烧的爱,但睡着的时候却不能。判断他是否每天都能喊出对章鱼烧的爱。这里,一天有\(24......
  • AtCoder Beginner Contest 361
    ABC361A-Insert题目传送门代码(签到题)#include<iostream>#include<string>#include<algorithm>usingnamespacestd;intn,m,x,a[111];intmain(){ cin>>n>>m>>x; for(inti=1;i<=n;++i)cin>>a[i]; for(inti=1;i&l......
  • AtCoder Beginner Contest 045
    A-Trapezoids#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmain(){ ios::sync_with_stdio(false),cin.tie(nullptr); inta,b,h; cin>>a>>b>>h; cout<<(a+b)*h/2; return0;}B-......
  • [AtCoder] E - Putting Candies
    ProblemLinkIfwepickA[i]the2ndtime,itmeanswehaveacycle.Proof:1sttimewepickA[i],thesumbeforeaddingA[i]isx;2ndtimewepickA[i],thesumbeforeaddingA[i]isy; Forthistohappenx%N==y%Nmusthold.Otherwisewewouldno......
  • 题解:AT_abc365_d [ABC365D] AtCoder Janken 3
    D-AtCoderJanken3题解题意:高桥和青木要玩石头剪刀布,给你一个长度为\(n\)的字符串\(s\),\(s\)表示青木在第\(i\)局游戏中的动作(R表示石头,P表示布,S表示剪刀。)。高桥不可以在任何一局中输给青木(即:高桥和青木只可以平局或高桥赢青木),且高桥第\(i\)局出的和第\(i-1\)局......
  • 题解:AtCoder Janken 3
    D-AtCoderJanken3题解题意高桥和青木要玩石头剪刀布,给你一个长度为\(n\)的字符串\(s\),\(s\)表示青木在第\(i\)局游戏中的动作(R表示石头,P表示布,S表示剪刀)。高桥不可以在任何一局中输给青木(即:高桥和青木只可以平局或高桥赢青木),且高桥第\(i\)局出的和第\(i-1\)局......
  • AtCoder Beginner Contest 044
    A-TakandHotels(ABCEdit)#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmain(){ ios::sync_with_stdio(false),cin.tie(nullptr); intn,k,x,y; cin>>n>>k>>x>>y; intans=0; if......
  • Solution - Atcoder ARC171D Rolling Hash
    对于这个\(\operatorname{hash}(A_L,\cdots,A_R)\),一个比较经典的想法是做差分,即令\(s_i=\sum\limits_{j=1}^iA_jB^{i-j}\)。于是\(\operatorname{hash}(A_L,\cdots,A_R)=s_R-s_{L-1}\timesB^{R-L+1}\not=0\)。那么也就是\(s_R\not=s_{L-1}\ti......
  • 蒟蒻CC的补题日记
    A——FindKDistinctPointswithFixedCentern为偶数输出(x−1,y−1),(x+1,y+1),...,(x−n/2,y−n/2),(x+n/2,y+n/2)(x-1,y-1),(x+1,y+1),...,(x-n/2,y-n/2),(x+n/2,y+n/2)(x−1,y−1),(x+1,y+1),...,(x−n/2,y......