• HDU


      这题我第一次想的就是直接模拟,因为我是这样感觉的,输入n是3次方,长度是5次方,加起来才8次方,里面的操作又不复杂,感觉应该能过,然而不如我所料,TLE了,玛德,这是第一次的代码。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    #define PI(A) printf("%d
    ",A)
    #define SI(N) scanf("%d",&(N))
    #define SII(N,M) scanf("%d%d",&(N),&(M))
    #define cle(a,val) memset(a,(val),sizeof(a))
    #define rep(i,b) for(int i=0;i<(b);i++)
    #define Rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define reRep(i,a,b) for(int i=(a);i>=(b);i--)
    const double EPS= 1e-9 ;
    
    /*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */
    
    const int MAXN= 100000 + 5 ;
    
    char str[MAXN];
    int N;
    
    
    int main()
    {
        while(~SI(N))
        {
            int x,y;
            scanf("%s",str);
            while(N--)
            {
                LL ans=1;
                SII(x,y);
                x--,y--;
                for (int i=x;i<=y;i++)
                {
                    ans=ans*((int)str[i]-28);
                    ans%=9973;
                }
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }

      之后想了一会,想不通,就查题解了,我看的是这个题解 http://www.cnblogs.com/inmoonlight/p/5512340.html

      看了之后,觉得有几点要注意:

      1.像这样求连乘的,一段区间的东西,一定要先打表,之后在输入查询,否则几乎绝对超时,比如求这题可以换成H(t)/H(s-1),由此可以想到,连加的时候也可以打表,那就是H(t)-H(s-1)

      2.看到大数相除,还取模,那就是逆元了,可以用 exgcd 或 费马小定理求,这里可以写个函数自己判断下m是不是素数,9973 显然是素数,所以就费马小定理。费马小定理,H(n)的逆元为H(n)MOD-2 % MOD,当MOD是素数时。

       之后,理所当然,AC

    #include <bits/stdc++.h>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    #define PI(A) printf("%d
    ",A)
    #define SI(N) scanf("%d",&(N))
    #define SII(N,M) scanf("%d%d",&(N),&(M))
    #define cle(a,val) memset(a,(val),sizeof(a))
    #define rep(i,b) for(int i=0;i<(b);i++)
    #define Rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define reRep(i,a,b) for(int i=(a);i>=(b);i--)
    const double EPS= 1e-9 ;
    
    /*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */
    
    const int MAXN= 100000 + 5 ;
    
    char str[MAXN];
    int h[MAXN];
    int N;
    int M=9973;
    
    //快速幂模板
    LL mod_pow(LL x,LL n,LL mod)
    {
        LL res=1;
        while(n>0){
            if (n&1) res=res*x%mod;
            x=x*x%mod;
            n>>=1;
        }
        return res;
    }
    
    
    int main()
    {
        while(~SI(N))
        {
            int x,y;
            scanf("%s",str);
            h[0]=1;
            //注意这是str[i]!='' 不是strlen(str) 如果换了 会超时,因为调用函数浪费时间,不信? 你自己试下,就知道了
            for (int i=0;str[i];i++)
            {
                h[i+1]=h[i]*(str[i]-28)%M;
            }
            while(N--)
            {
                SII(x,y);
                printf("%lld
    ",h[y]*mod_pow(h[x-1],M-2,M)%M);
            }
        }
        return 0;
    }

      做完这题,有个感悟,就是不管什么题,不求速度,只求质量,一定要搞懂,就算一周只看一个题,只要搞懂了,绝对比看100道,一道都没懂好。

      在附赠一个测素数的代码:

    #include <bits/stdc++.h>
    using namespace std;
    int N;
    int main()
    {
        //PS:9973   1e9+7  都是素数
        while(cin>>N)
        {
            bool fl=1;
            for (int i=2;i<=sqrt(N);i++)
            {
                if (N%i==0)
                    fl=0;
            }
            puts(fl&&N>1?"yes":"no");
        }
    
        return 0;
    }
  • 相关阅读:
    动态表单功能
    IDEA2019版Run Dashboard调出方案
    js页面传递参数为中文乱码问题解决方法
    layui 一行多列控件时使用table布局
    npm 安装包失败 --- 清除npm缓存
    解析数据库连接字符串 (将Data Source、Initial Catalog、User ID、Password取出)
    SQL SERVER 存储过程语法
    mvc5 跨域访问
    钟表
    MVC session过期如何处理跳转(转)
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5672627.html
Copyright © 2020-2023  润新知