• 牛客OI赛制测试赛3游记


    A - 数字权重

    题目大意:

    一个(n)位的数字。设第(i)位的数为(a_i),其中(a_1)为最高位,(a_n)为最低位,(k)为给定的数字。求同时满足满足以下两个条件的数的个数:

    1. 不含前导(0)
    2. (sum_{i=2}^n(a_i-a_{i-1})=k)

    (n,|k|le10^{13})

    思路:

    对和式稍加变形得(a_n-a_1=k),因此我们只需要考虑(a_1)(a_n),其余数位(0sim 9)随便放即可。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using int64=long long;
    inline int64 getint() {
        register char ch;
        register bool neg=false;
        while(!isdigit(ch=getchar())) neg|=ch=='-';
        register int64 x=ch^'0';
        while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
        return neg?-x:x;
    }
    constexpr int mod=1e9+7;
    inline int power(int a,int64 k) {
        int ret=1;
        for(;k;k>>=1) {
            if(k&1) ret=(int64)ret*a%mod;
            a=(int64)a*a%mod;
        }
        return ret;
    }
    int main() {
        const int64 n=getint(),k=getint();
        if(std::abs(k)>9) {
            puts("0");
            return 0;
        }
        int ans=power(10,n-2);
        if(k>=0) ans=ans*(9-k)%mod;
        if(k<0) ans=ans*(10+k)%mod;
        printf("%d
    ",ans);
        return 0;
    }
    

    B - 毒瘤xor

    CC-XXOR

    C - 硬币游戏

    题目大意:

    A和B各有一行长度为(2n(nle10^6))的01序列,A先取,每次只能取两个人之前都没取过的位置,这样(n)次后两个人就得到了长度为(n)的数字串,谁的字典序大谁就赢了。若两人都按照最优策略,问最后谁赢(或平手)。

    思路:

    每次贪心取未被选择位置上的(1),如果有很多(1)那么优先取对方也是(1)的。用堆来维护,时间复杂度(mathcal O(nlog n))

    源代码:

    #include<queue>
    #include<cstdio>
    #include<cctype>
    inline int getint() {
        register char ch;
        while(!isdigit(ch=getchar()));
        register int x=ch^'0';
        while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
        return x;
    }
    inline bool getval() {
        register char ch;
        while(!isalpha(ch=getchar()));
        return ch=='U';
    }
    const int N=2e6+1;
    bool a[N],b[N],mark[N];
    struct Node {
        bool a,b;
        int id;
        bool operator < (const Node &rhs) const {
            if(a^rhs.a) return !a;
            if(b^rhs.b) return !b;
            return id<rhs.id;
        }
    };
    std::priority_queue<Node> q[2];
    int main() {
        const int n=getint();
        for(register int i=1;i<=n*2;i++) a[i]=getval();
        for(register int i=1;i<=n*2;i++) b[i]=getval();
        for(register int i=1;i<=n*2;i++) {
            q[0].push((Node){a[i],b[i],i});
            q[1].push((Node){b[i],a[i],i});
        }
        for(register int i=1;i<=n;i++) {
            while(mark[q[0].top().id]) q[0].pop();
            a[i]=q[0].top().a;
            mark[q[0].top().id]=true;
            while(mark[q[1].top().id]) q[1].pop();
            b[i]=q[1].top().a;
            mark[q[1].top().id]=true;
        }
        for(register int i=1;i<=n;i++) {
            if(a[i]==b[i]) continue;
            puts(a[i]?"clccle trl!":"sarlendy tql!");
            return 0;
        }
        puts("orz sarlendy!");
        return 0;
    }
    

    D - 粉樱花之恋

    题目大意:

    求斐波那契数列前(n(nle10^{18}))项和。

    思路:

    找规律可以发现前(n)项和(F(n)=f(n+3)-1),因此直接矩阵快速幂或者折半公式即可。

    时间复杂度(mathcal O(nlog n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<unordered_map>
    using int64=long long;
    inline int64 getint() {
        register char ch;
        while(!isdigit(ch=getchar()));
        register int64 x=ch^'0';
        while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
        return x;
    }
    const int64 mod=998244353;
    std::unordered_map<int64,int> m;
    inline int64 sqr(const int64 &x) {
        return x*x;
    }
    int64 f(const int64 &n) {
        if(m[n]) return m[n];
        if(n==1||n==2) return m[n]=1;
        if(n&1) return m[n]=(sqr(f(n/2+1))+sqr(f(n/2)))%mod;
        return m[n]=(f(n/2-1)*2+f(n/2))*f(n/2)%mod;
    }
    int main() {
        printf("%lld
    ",f(getint()+3)-1);
        return 0;
    }
    

    E - 符合条件的整数

    题目大意:

    ([2^n,2^m)(n,mle65))内满足(xequiv1pmod{7})(x)个数。

    思路:

    使用__int128直接算即可。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<iostream>
    typedef unsigned __int128 uint128;
    std::ostream &operator <<(std::ostream &os,const uint128 &x) {
        if(x>=10) os<<x/10;
        return os<<int(x%10);
    }
    inline int getint() {
        register char ch;
        while(!isdigit(ch=getchar()));
        register int x=ch^'0';
        while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
        return x;
    }
    int main() {
        const int n=getint(),m=getint();
        std::cout<<(((uint128)1<<m)-2)/7-(((uint128)1<<n)-2)/7<<std::endl;
        return 0;
    }
    

    F - 可爱即正义

    题目大意:

    给你一个字符串(s),问是否能通过交换两个字符使得其不包括suqingnianloveskirito作为子串。

    思路:

    哈希以后统计suqingnianloveskirito的出现次数,并记录出现位置,分情况讨论即可。

    源代码:

    明明很多锅(比如(cnt=0)时交换前两个可能产生新的suqingnianloveskirito),但还是过了。

    #include<cstdio>
    #include<cstring>
    using uint64=unsigned long long;
    const int N=1e6+2,base=31;
    char s[N];
    const char t[23]="suqingnianloveskirito";
    uint64 hash[N],pwr[N],tmp;
    int pos[N];
    inline uint64 calc(const int &i) {
        return hash[i]-hash[i-21]*pwr[21];
    }
    int main() {
        scanf("%s",&s[1]);
        const int n=strlen(&s[1]);
        if(n==1) {
            puts("No");
            return 0;
        }
        for(register int i=pwr[0]=1;i<=n;i++) {
            pwr[i]=pwr[i-1]*base;
            hash[i]=hash[i-1]*base+s[i]-'a'+1;
        }
        for(register int i=1;i<=21;i++) {
            tmp=tmp*base+t[i]-'a'+1;
        }
        int cnt=0;
        for(register int i=1;i<=n;i++) {
            if(i>=21&&calc(i)==tmp) {
                pos[++cnt]=i;
            }
        }
        if(cnt==0) {
            puts("Yes
    1 2
    ");
            return 0;
        }
        if(cnt==1) {
            puts("Yes");
            printf("%d %d
    ",pos[1],pos[1]-1);
            return 0;
        }
        if(cnt==2) {
            puts("Yes");
            printf("%d %d
    ",pos[1],pos[2]-1);
            return 0;
        }
        puts("No");
        return 0;
    }
    
  • 相关阅读:
    annotation:@Override出现The method of type must override asuperclass解决方案
    把Object对象转换成XML格式的数据
    把用SQL查询的分页对象转化为内容为Object的分页对象
    java实现webservice实例
    把Excel表中的数据导入sql service数据库的语句
    把汉字串转成对应的汉语拼音
    JDBC连接mySQL数据库流程及其原理
    oracle将多列进行合并
    源码分析 | ClickHouse和他的朋友们(13)ReplicatedMergeTree表引擎及同步机制
    源码分析 | ClickHouse和他的朋友们(1)编译、开发、测试
  • 原文地址:https://www.cnblogs.com/skylee03/p/9637996.html
Copyright © 2020-2023  润新知