• “字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛



    layout: post
    title: “字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛
    author: "luowentaoaa"
    catalog: true
    mathjax: true
    tags:

    • 数学
    • 矩阵快速幂
    • 权值线段树

    hzy 和zsl 的生存挑战 (签到)

    我还是要吐槽一下,题目都说了两人没有交流还怎么能推出一个人相同一个人不相同,如果两个人都相同呢?

    puts("1.00
    1.00
    1.00
    1.00");
        return 0;
    }
    

    人类史上最大最好的希望事件 (矩阵快速幂求fib前缀平方和)

    思路

    斐波那契数列前n项和答案为(F_{N}*F_{N+1})

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=192600817;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    
    ll x,y;
    typedef vector<ll>vec;
    typedef vector<vec>mat;
    mat mul(mat& A,mat &B){
        mat C(A.size(),vec(B[0].size()));
        for(int i=0;i<A.size();i++)
            for(int k=0;k<B.size();k++)
            if(A[i][k])
                for(int j=0;j<B[0].size();j++)
                C[i][j]=(C[i][j]+A[i][k]*B[k][j]%mod+mod)%mod;
        return C;
    }
    mat Pow(mat A,ll n){
        mat B(A.size(),vec(A.size()));
        for(int i=0;i<A.size();i++)B[i][i]=1;
        for(;n;n>>=1,A=mul(A,A))
            if(n&1)B=mul(B,A);
        return B;
    }
    int main(){
        int q;
        while(~scanf("%d",&q)){
            for(int i=1;i<=q;i++){
                ll a,b,c,d;
                scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
                a=a*4+b+1;b=c*4+d+1;
                if(a>b)swap(a,b);
                a--;
                mat A(2,vec(2)),B(2,vec(2)),F1(2,vec(1)),F2(2,vec(1));
                A[0][0]=A[0][1]=A[1][0]=1;A[1][1]=0;
                F1[0][0]=1;F1[1][0]=0;
                B[0][0]=B[0][1]=B[1][0]=1;B[1][1]=0;
                F2[0][0]=1;F2[1][0]=0;
                A=Pow(A,a);
                B=Pow(B,b);
                F1=mul(A,F1);
                F2=mul(B,F2);
                ll ans1=F1[0][0]*F1[1][0]%mod;
                ll ans2=F2[0][0]*F2[1][0]%mod;
                printf("%lld
    ",(ans2-ans1+mod)%mod);
            }
        }
        return 0;
    }
    

    超级无敌简单题 (规律)

    思路

    发现如果出现4就会出现死循环

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const ll mod=1e8+7;
    const int maxn=5e5+50;
    const int inf=1e8;
    vector<int>ve;
    bool isok(int n){
        while(n!=1&&n!=4){
            ll sum=0;
            while(n){
                sum+=(n%10)*(n%10);
                n/=10;
            }
            n=sum;
        }
        return n==1;
    }
    int main()
    {
        int q;
        for(int i=1;i<1100000;i++){
            if(isok(i))ve.push_back(i);
        }
        //cout<<ve.size()<<endl;
        /*for(int i=0;i<ve.size();i++){
            cout<<ve[i]<<endl;
        }*/
        scanf("%d",&q);
        while(q--){
            int n;
            scanf("%d",&n);
            printf("%d
    ",ve[n-1]);
        }
        return 0;
    }
    

    免费送气球 (权值线段树)

    思路

    对于每个数存一个数量和val 然后判断数量是否大于查询数量,

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll inf=1e16;
    const ll mod=1e9+7;
    const int maxn=1e5+50;
    
    ll sum[maxn*40],val[maxn*40];
    int ls[maxn*40],rs[maxn*40];
    int cnt;
    void update(int &o,int l,int r,int k,int num){
        if(!o)o=++cnt;
        sum[o]+=k;
        val[o]+=1LL*k*num;
        val[o]%=mod;
        if(l==r)return;
        int mid=(l+r)/2;
        if(num<=mid)update(ls[o],l,mid,k,num);
        else update(rs[o],mid+1,r,k,num);
    }
    ll query(int o,int l,int r,ll k){
        if(l==r)return 1LL*k*l%mod;
        int mid=(l+r)/2;
        ll res=0;
        if(k>sum[ls[o]])res=(val[ls[o]]+query(rs[o],mid+1,r,k-sum[ls[o]]));
        else res=query(ls[o],l,mid,k);
        return res%mod;
    }
    
    
    int main()
    {
        int q,rt=0;
        cin>>q;
        while(q--){
            int op;ll l,r;
            cin>>op>>l>>r;
            if(op==1)update(rt,0,1e9,l,r);
            else{
                cout<<(query(rt,0,1e9,r)-query(rt,0,1e9,l-1)+mod)%mod<<endl;
            }
        }
        return 0;
    }
    

    简单数学题 (数学题)

    思路

    (F(n) = sum_{i=1}^n (i imes sum_{j=i}^n C_j^i))

    ->$F(n)=sum_{i=1}{n}sum_{j=i}{n} i imes C_{j}^{i} $

    其中$ sum C_{j}^{i}$ 是杨辉三角的一条斜线

    然后把i乘入这个斜线中,发现杨辉三角变成一个新的少了一维的杨辉三角

    发现新的杨辉三角是之前的杨辉三角每一层的元素乘上层号

    然后就是变成求(sum_{i=1}^{n} i imes 2^{i-1})

    (1 imes 2+2 imes2^1 +3 imes 2^2+dots n imes2^{n-1})

    然后拆项为

    [2^1+2^2+2^3+2^4 dots2^{n-1}\+2^2+2^3+2^4+dots2^{n-1} \ +2^3+2^4+dots2^{n-1}\+2^4+dots2^{n-1}\ dots ]

    根据等比数列(s_n=frac{a_1(1-a_n)}{1-q}=frac{a_nq-a_1}{q-1})

    整理

    第一行变成(2^n-2^0) 第二行变成(2^n-2^1) 第n行变成(2^n-2^{n-1})

    再整理变成(n imes2^n-(2^n-1)=(n-1) imes2^n+1)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const ll mod=1e9+7;
    const int maxn=5e5+50;
    const int inf=1e8;
    ll ksm(ll a,ll b){
        ll ans=1;
        while(b){
            if(b&1)ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans;
    }
    int main()
    {
        ll n;
        while(~scanf("%lld",&n)){
            ll ans=ksm(2,n);
            n%=mod;
            ans=(ans*(n-1))%mod;
            ans+=1;ans%=mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    zyb的面试 (原题)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const ll mod=1e9+7;
    const int maxn=1e3+50;
    const ll inf=1e17;
    int cal(int n,int k){
        int cur=1;
        k=k-1;
        while(k>0){
            int step=0,first=cur,last=cur+1;
            while(first<=n){
                step+=min(n+1,last)-first;
                first*=10;
                last*=10;
            }
            if(step<=k){
                cur++;
                k-=step;
            }
            else{
                cur*=10;
                k-=1;
            }
        }
        return cur;
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--){
            int n,k;
            cin>>n>>k;
            cout<<cal(n,k)<<endl;
        }
        return 0;
    }
    

    Count (矩阵快速幂)

    思路

    考虑矩阵快速幂 考虑要从前一项得到后一项的(n^3)

    根据公式((n+1)^3=n^3+3*n^2+3*n+1)

    推出(f(n)=f(n-1)+2*f(n-2)+n^3+3*n^2+3*n+1)

    所以构造一个矩阵就行了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pp pair<int,int>
    const ll mod=123456789;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    #define bug cout<<"here"<<endl;
    typedef vector<ll>vec;
    typedef vector<vec>mat;
    
    mat mul(mat& A,mat &B){
        mat C(A.size(),vec(B[0].size()));
        for(int i=0;i<A.size();i++)
            for(int k=0;k<B.size();k++)
            if(A[i][k])
                for(int j=0;j<B[0].size();j++)
                C[i][j]=(C[i][j]+A[i][k]*B[k][j]%mod+mod)%mod;
        return C;
    }
    mat Pow(mat A,ll n){
        mat B(A.size(),vec(A.size()));
        for(int i=0;i<A.size();i++)B[i][i]=1;
        for(;n;n>>=1,A=mul(A,A))
            if(n&1)B=mul(B,A);
        return B;
    }
    
    int main(){
        int q;
        scanf("%d",&q);
        while(q--){
            ll n;
            scanf("%lld",&n);
            if(n==1){
                printf("1
    ");continue;
            }
            else if(n==2){
                printf("2
    ");continue;
            }
            mat a(6,vec(6));
            a[0][0]=1;a[0][1]=2;a[0][2]=1;a[0][3]=3;a[0][4]=3;a[0][5]=1;
            a[1][0]=1;a[1][1]=0;a[1][2]=0;a[1][3]=0;a[1][4]=0;a[1][5]=0;
            a[2][0]=0;a[2][1]=0;a[2][2]=1;a[2][3]=3;a[2][4]=3;a[2][5]=1;
            a[3][0]=0;a[3][1]=0;a[3][2]=0;a[3][3]=1;a[3][4]=2;a[3][5]=1;
            a[4][0]=0;a[4][1]=0;a[4][2]=0;a[4][3]=0;a[4][4]=1;a[4][5]=1;
            a[5][0]=0;a[5][1]=0;a[5][2]=0;a[5][3]=0;a[5][4]=0;a[5][5]=1;
            mat f(6,vec(1));
            f[0][0]=2;
            f[1][0]=1;
            f[2][0]=8;
            f[3][0]=4;
            f[4][0]=2;
            f[5][0]=1;
            a=Pow(a,n-2);
            f=mul(a,f);
            printf("%lld
    ",f[0][0]);
        }
        return 0;
    }
    
  • 相关阅读:
    学会拒绝,把时间用在更重要的事情上
    5G即将到来!我们需要一部怎样的手机呢?
    互联网早期是如何发展起来的?
    程序员需要明白这九件事
    centos7安装出现license information(license not accepted)解决办法
    CentOS6.5下安装MySql5.7.17
    Linux操作系统下MySQL的安装 --转
    SecureCRT_教程--1(windows远程登录linux)
    CentOS-7中安装与配置Tomcat8.5
    CentOS7使用firewalld打开关闭防火墙与端口
  • 原文地址:https://www.cnblogs.com/luowentao/p/10545142.html
Copyright © 2020-2023  润新知