zoukankan      html  css  js  c++  java
  • 2020杭电多校第一场

    http://acm.hdu.edu.cn/search.php?field=problem&key=2020+Multi-University+Training+Contest+1&source=1&searchmode=source

    1004 Distinct Sub-palindromes

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=300;
    const int SIZE=3e5+5;
    const long long mod=998244353;
    typedef long long ll;
    //typedef __int128 LL;
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    ll quickpow(ll a,ll b,ll p)
    {
        ll res=1%p;
        a%=p;
        while(b!=0)
        {
            if(b&1)
                res=(res*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return res;
    }
    
    int main()
    {
    
        ll ans1=(24*25*26)%mod;
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n;
            scanf("%lld",&n);
            ll ans=0;
            if(n<=3)ans=quickpow(26,n,mod);
            else ans=ans1;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    1005 Fibonacci Sum  二次剩余+Fibonacci

     思路:

    参考(照搬 博客:https://www.cnblogs.com/stelayuri/p/13357775.html

     

     

     

     

    可暴力找mod1e9+9意义下√5 的值是383008016

    for(ll i=1;i<mod;i++)
    {
        if(i*i%mod==5)
        {
            printf("%lld
    ",i);
            break;
        }
    }

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+5;
    const int mod=1e9+9;
    typedef long long ll;
    typedef  unsigned long long ull;
    typedef __int128 LL;
    const double eps=10e-8;
    const double pi=acos(-1.0);
    #define between(x,a,b)(a<=x && x<=b)
    //const int dir[8][2]={1,0,0,1,-1,0,0,-1-1,-1,-1,1,1,-1,1,1};
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    typedef pair<ll,ll> pII;
    typedef pair<int,int> pii;
    typedef pair<int,ll> piI;
    ll fac[MAXN],invfac[MAXN],inv[MAXN];
    void init(int n)
    {
        invfac[0]=1;
        fac[0]=1;
        inv[1]=1;
        for(int i=2;i<=n;++i) inv[i]=((mod-mod/i)*inv[mod%i])%mod;
        for(int i=1;i<=n;++i) fac[i]=fac[i-1]*i%mod,invfac[i]=invfac[i-1]*inv[i]%mod;
    }
    ll C(int n,int m)
    {
        return fac[n]*invfac[m]%mod*invfac[n-m]%mod;
    }
    ll quickpow(ll a,ll b,ll p) //(a^b)%p
    {
        ll res=1%p;
        a%=p;
        while(b!=0)
        {
            if(b&1)
                res=(res*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return res;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("1.in", "r", stdin);
        freopen("debug.out", "w", stdout);
    #endif
        init(1e5);
        ll d=276601605,a=691504013,b=308495997;
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n,c,k;
            ll ans=0;
            scanf("%lld%lld%lld",&n,&c,&k);
            ll ac=quickpow(a,c%(mod-1),mod);
            ll bc=quickpow(b,c%(mod-1),mod);
            ll tmp=(bc*quickpow(ac,mod-2,mod))%mod;
            ll aq=quickpow(ac,k,mod);//首项和公比
    
            for(int i=0;i<=k;i++)
            {
                ll tmp1,tmp2;
                if(i%2==0)tmp1=C(k,i);
                else tmp1=-1*C(k,i);
    
                if(aq==1)tmp2=n%mod;
                else tmp2=(aq*(quickpow(aq,n%(mod-1),mod)-1+mod)%mod)*quickpow(aq-1,mod-2,mod)%mod;
    
                ans=(ans+(tmp1*tmp2%mod))%mod;
                ans=(ans+mod)%mod;
                aq=aq*tmp%mod;
            }
            ans=ans*quickpow(d,k,mod)%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    aqn也可以通过递推求,快一点;

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+5;
    const int mod=1e9+9;
    typedef long long ll;
    typedef  unsigned long long ull;
    typedef __int128 LL;
    const double eps=10e-8;
    const double pi=acos(-1.0);
    #define between(x,a,b)(a<=x && x<=b)
    //const int dir[8][2]={1,0,0,1,-1,0,0,-1-1,-1,-1,1,1,-1,1,1};
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    typedef pair<ll,ll> pII;
    typedef pair<int,int> pii;
    typedef pair<int,ll> piI;
    ll fac[MAXN],invfac[MAXN],inv[MAXN];
    void init(int n)
    {
        invfac[0]=1;
        fac[0]=1;
        inv[1]=1;
        for(int i=2;i<=n;++i) inv[i]=((mod-mod/i)*inv[mod%i])%mod;
        for(int i=1;i<=n;++i) fac[i]=fac[i-1]*i%mod,invfac[i]=invfac[i-1]*inv[i]%mod;
    }
    ll C(int n,int m)
    {
        return fac[n]*invfac[m]%mod*invfac[n-m]%mod;
    }
    ll quickpow(ll a,ll b,ll p) //(a^b)%p
    {
        ll res=1%p;
        a%=p;
        while(b!=0)
        {
            if(b&1)
                res=(res*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return res;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("1.in", "r", stdin);
        freopen("debug.out", "w", stdout);
    #endif
        init(1e5);
        ll d=276601605,a=691504013,b=308495997;
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n,c,k;
            ll ans=0;
            scanf("%lld%lld%lld",&n,&c,&k);
            ll ac=quickpow(a,c%(mod-1),mod);
            ll bc=quickpow(b,c%(mod-1),mod);
            ll tmp=(bc*quickpow(ac,mod-2,mod))%mod;// (b/a)^c
            ll tmpn=quickpow(tmp,n%(mod-1),mod);// ((b/a)^c)^n
            ll aq=quickpow(ac,k,mod);//首项和公比
            ll aqn=quickpow(aq,n%(mod-1),mod);//公比的n次方
            for(int i=0;i<=k;i++)
            {
                ll tmp1,tmp2;
                if(i%2==0)tmp1=C(k,i);
                else tmp1=-1*C(k,i);
    
                if(aq==1)tmp2=n%mod;
                else tmp2=(aq*(aqn-1+mod)%mod)*quickpow(aq-1,mod-2,mod)%mod;
    
                ans=(ans+(tmp1*tmp2%mod))%mod;
                ans=(ans+mod)%mod;
                aq=aq*tmp%mod;
                aqn=aqn*tmpn%mod;
            }
            ans=ans*quickpow(d,k,mod)%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    1009  Leading Robots  单调栈

    题意:

    有n个机器人,每个机器人有一个初始位置和加速度,同时向右移动,跑道很长,没有终点。在某个特定时间,如果机器人是最右边且唯一的,那么它就是当时的领先机器人。问:领先机器人的数量。

    题解:

    方法一:

    参考博客:https://blog.csdn.net/qq_44828887/article/details/107499606

    加速度从小到排序,相同加速度位置从小到大排序,后面的机器人肯定可以超过前面的机器人(同加速度,同位置除外);

    维护一个栈,栈中的机器人是领先机器人,当前入栈的机器人肯定可以超过栈中的机器人。

    当后面(正要入栈的)机器人的位置大于等于前面(栈中)机器人的位置时,位置大的肯定会超过前一个(栈中)机器人,前一个机器人不可能是领先机器人,位置相等且加速度相同的机器人并行也不可能是领先机器人,所以出栈;

    当栈中机器人>1时,如果栈顶前两个机器人相遇的时间 大于 栈顶机器人和正要入栈的机器人相遇的时间,栈顶机器人出栈;

    最后判断栈中是否有并行机器人,有就减掉。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=5e4+5;
    const int SIZE=5e4+5;
    const long long mod=998244353;
    typedef long long ll;
    //typedef __int128 LL;
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    int st[MAXN];
    struct node
    {
        ll l,a;
        bool operator<(const node &Node)const{
            if(a==Node.a)return l<Node.l;
            return a<Node.a;
        }
    };
    node p[MAXN];
    map<node,int>mp;
    bool check(node x,node y,node z)
    {
        return (y.l-z.l)*(y.a-x.a)-(x.l-y.l)*(z.a-y.a)<=0;
    }
    int main()
    {
    
        int t;
        scanf("%d",&t);
        while(t--)
        {
            mp.clear();
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%lld%lld",&p[i].l,&p[i].a);
                mp[p[i]]++;
            }
    
            sort(p+1,p+1+n);
    
            int top=0;
            for(int i=1;i<=n;i++)
            {
                while((top>0&&p[i].l>=p[st[top]].l)||(top>1&&check(p[st[top-1]],p[st[top]],p[i])))--top;
                st[++top]=i;
            }
            int ans=top;
            for(int i=1;i<=top;i++)
            {
                if(mp[p[st[i]]]>1)ans--;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

     方法二:(排序方法不一样

    位置从大到小排序,同位置加速度从大到小排序。

    位置小且加速度小于等于前面机器人的肯定不会超过前面的机器人,不进入栈;

    当加速度大时同样判断相遇时间,方法同上。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=5e4+5;
    const int SIZE=5e4+5;
    const long long mod=998244353;
    typedef long long ll;
    //typedef __int128 LL;
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    int st[MAXN];
    struct node
    {
        ll l,a;
        bool operator<(const node &Node)const{
            if(l==Node.l)return a>Node.a;
            return l>Node.l;
        }
    };
    node p[MAXN];
    map<node,int>mp;
    bool check(node x,node y,node z)
    {
        return (y.l-z.l)*(y.a-x.a)-(x.l-y.l)*(z.a-y.a)<=0;
    }
    int main()
    {
    
        int t;
        scanf("%d",&t);
        while(t--)
        {
            mp.clear();
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%lld%lld",&p[i].l,&p[i].a);
                mp[p[i]]++;
            }
    
            sort(p+1,p+1+n);
    
            int top=0;
            for(int i=1;i<=n;i++)
            {
                if(top>0&&p[st[top]].a>=p[i].a)continue;
                while(top>1&&check(p[st[top-1]],p[st[top]],p[i]))--top;
                st[++top]=i;
            }
            int ans=top;
            for(int i=1;i<=top;i++)
            {
                if(mp[p[st[i]]]>1)ans--;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    也可以 位置从大到小排序,同位置加速度从小到大排序。

    但是要注意这个案例,再加一个判段就可以:

    1

    2

    4 6

    4 7

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=5e4+5;
    const int SIZE=5e4+5;
    const long long mod=998244353;
    typedef long long ll;
    //typedef __int128 LL;
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    int st[MAXN];
    struct node
    {
        ll l,a;
        bool operator<(const node &Node)const{
            if(l==Node.l)return a<Node.a;
            return l>Node.l;
        }
    };
    node p[MAXN];
    map<node,int>mp;
    bool check(node x,node y,node z)
    {
        return (y.l-z.l)*(y.a-x.a)-(x.l-y.l)*(z.a-y.a)<=0;
    }
    int main()
    {
    
        int t;
        scanf("%d",&t);
        while(t--)
        {
            mp.clear();
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%lld%lld",&p[i].l,&p[i].a);
                mp[p[i]]++;
            }
    
            sort(p+1,p+1+n);
    
            int top=0;
            for(int i=1;i<=n;i++)
            {
                if(top>0&&p[st[top]].a>=p[i].a)continue;
                while((top>1&&check(p[st[top-1]],p[st[top]],p[i]))||(top>0&&p[st[top]].l==p[i].l))--top;
                st[++top]=i;
            }
            int ans=top;
            for(int i=1;i<=top;i++)
            {
                if(mp[p[st[i]]]>1)ans--;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

     

  • 相关阅读:
    wget(转)
    852. Peak Index in a Mountain Array
    617. Merge Two Binary Trees
    814. Binary Tree Pruning
    657. Judge Route Circle
    861. Score After Flipping Matrix
    832. Flipping an Image
    461. Hamming Distance
    654. Maximum Binary Tree
    804. Unique Morse Code Words
  • 原文地址:https://www.cnblogs.com/MZRONG/p/13362664.html
Copyright © 2011-2022 走看看