zoukankan      html  css  js  c++  java
  • 2017 11 6模拟赛T1

    作为一个毒瘤出题人(wzy:我不是毒瘤出题人,这些题明明很水的),wzy的题干十分复杂,但是把题意简化之后,相当简单粗暴。。。

    求首项为1,等比为m,项数为t的等比数列的和,答案对k取模

    不保证m与k互质

    如果m与k互质的话,用等比数列的求和公式在求个逆元就能解决了,但是本题显然不能,于是必须考虑不含有除法的算法

    于是就有了分治求等比数列和的办法。

    设s(x)为等比数列的第n项

    由等比数列的性质得到s(y)=s(x)*m^(y-x) (y>x)

    将一个长度为2r的等比数列拆分成登场的两部分,对应的项的比均为m^r,所以两部分和的差值也为m^r,所以只需要计算出前r项的和,就可以直接得到后r项的和。

    如果数列的长度为2r+1,那么必须手动计算出第2r+1项的值,然后将后面的2r项拆分计算。

    对于整个数列,递归计算,便可以在logt的时间内求出解。

    #include<cstdio>
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    int m,t,k;
    long long ksm(long long a,long long b)
    {
        long long s=a,re=1;
        while(b)
        {
            if(b&1) re=re*s%k;
            s=s*s%k;
            b>>=1;
        }
        return re%k;
    }
    long long sum(int l,int r)
    {
        if(l==r) return 1; 
        if((r-l+1)&1) return (ksm(m,r)+sum(l,(r-1)>>1)*(ksm(m,((r-1)>>1)+1)+1))%k;
        else return (sum(l,r>>1)*(ksm(m,(r>>1)+1)+1))%k;
    }
    int main()
    {
        read(m);read(t);read(k);
        printf("%d",sum(0,t-1));
        return 0;
    }
  • 相关阅读:
    文件夹打开对话框
    文件打开对话框
    HOOK函数(二)——全局HOOK
    HOOK函数(一)——进程内HOOK
    抓包
    List 访问
    坑爹的EL 表达式。
    tomcat 虚拟目录的安全问题
    框架
    程序员相关词汇
  • 原文地址:https://www.cnblogs.com/zeroform/p/7794121.html
Copyright © 2011-2022 走看看