幻想

来源:互联网 发布:远野贵树是什么程序员 编辑:程序博客网 时间:2024/06/08 05:36

题目描述

这里写图片描述

容易归纳出Si就是i在k进制数下各数位上的数的和再模k。
证明很简单。
我们只需要维护k进制分解即可。
用一个数组维护,每次把最低位+1,然后考虑进位。
均摊分析这是线性的:
设势函数为k-1的数量。
每次若进位了s个,那么势函数减少了s,并可能增加1,实际消耗时间为s+1,因此Ai<=s+1-s+1=2
均摊复杂度为O(1)
优化常数使用模优化即可

#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;const ll mo=4294967296;const int a=20000116,b=804,c=233;ll s[70];ll i,j,k,l,r,h,m,t,ans,ca,top;ll read(){    ll x=0;    char ch=getchar();    while (ch<'0'||ch>'9') ch=getchar();    while (ch>='0'&&ch<='9'){        x=x*10+ch-'0';        ch=getchar();    }    return x;}int main(){    freopen("fantasy.in","r",stdin);freopen("fantasy.out","w",stdout);    ca=read();    while (ca--){        k=read();l=read();r=read();        //l--;r--;        top=t=0;        j=l;        while (j){            s[top]=j%k;            t+=s[top];            if (t>=k) t-=k;            j/=k;            top++;        }        m=l%a;        h=(m*m+l+b)/c;        //printf("%d\n",h);        ans=h*t%mo;        fo(i,l+1,r){            s[0]++;t++;            if (t>=k) t-=k;            j=0;            while (s[j]==k){                //t-=k;                s[j]=0;                s[++j]++;                t++;                if (t>=k) t-=k;            }            m++;            if (m==a) m=0;            h=(m*m+i+b)/c;            //printf("%d\n",h);            ans=ans+h*t%mo;            if (ans>=mo) ans-=mo;        }        printf("%lld\n",ans);        fo(i,0,65) s[i]=0;    }}
0 0