zoukankan      html  css  js  c++  java
  • 题解[清华集训2012]模积和

    做这题之前我先做了一道水题也就是这题的弱化版热了热身。

    弱化版水题:P2261 [CQOI2007]余数求和

    先讲弱化版的。我们知道一个结论就是k%i=k-k/i*i;

    那么我们就把取模拆成这种形式。(下文默认i∈[1,n])

    很明显∑(k%i)可以拆成∑k-∑k/i*i,化简一下就是n*k-∑k/i*i。然后我们注意到对于一些i,k/i是一样的,就是数论分块里面块的大小。

    再结合高斯速算公式来一波,代码就很好写了。

    注意特殊情况就是k/l==0,此时不能直接(k/(k/l)),要把r设为n

    大概这样。

     1 #include<cstdio>
     2 #define it register int
     3 #define il inline
     4 int n,k;
     5 long long ans;
     6 il int Min(it p,it q){
     7     return p<q?p:q;
     8 }
     9 int main(){
    10     scanf("%d%d",&n,&k),ans=1ll*n*k;
    11     for(it l=1,r;l<=n;l=r+1)
    12         r=(k/l?Min(k/(k/l),n):n),ans=ans-1ll*(r-l+1)*(l+r)/2*1ll*(k/l); 
    13     printf("%lld",ans);
    14     return 0;
    15 }
    View Code

    然后我们讲主题:P2260 [清华集训2012]模积和

    由于我不会用LaTeX写数学公式,所以转一篇博文:戳这里 讲的非常清楚。

    这里稍微提一下。

    首先求逆元先分解质因数然后用a-1 mod p = aΦ(p)-1 mod p 去计算

    然后就是把 i mod j 转化为 i-(i/j)*j 其中i/j由于c++的性质自动下取整

    接着就是容斥原理把i!=j给消掉

    然后整理一下式子,把剩下的往里面代。

    一个小细节就是默认n<=m 如果读入的时候n>m就交换一下

     1 #include<cstdio>
     2 #define it register int
     3 #define il inline
     4 #define rll register long long
     5 typedef long long ll;
     6 typedef unsigned long long ull;
     7 typedef long double ldb;
     8 const long long p=19940417;
     9 ll inv,n,m,ans;
    10 il ll mul(ll a,ll b){
    11     return (a*b-(ull)((ldb)a/p*b+1e-7)*p+p)%p;
    12 }
    13 il void ksm(ll x,ll l){
    14     inv=1;
    15     while(l){
    16         if(l&1) inv=mul(inv,x);
    17         l>>=1,x=mul(x,x);
    18     }
    19 }
    20 il ll sumsl(ll l,ll r){
    21     return 1ll*(l+r)*(r-l+1)/2%p;
    22 }
    23 il ll sumn2(ll x){
    24     return mul(mul(x,x+1),mul(x<<1|1,inv));
    25 }
    26 il ll rc(ll x){
    27     ll now=0;
    28     for(rll l=1,r;l<=x;l=r+1)
    29         r=(x/(x/l)),now=(now+mul(x,r-l+1)-mul(sumsl(l,r),x/l)+p)%p;
    30     return now;
    31 }
    32 il ll mol(ll x){
    33     return x<0?x+p:(x>=p?x-p:x);
    34 }
    35 il ll Min(ll p,ll q){
    36     return p<q?p:q;
    37 }
    38 int main(){
    39     scanf("%lld%lld",&n,&m);
    40     if(n>m) n+=m,m=n-m,n-=m;
    41     ksm(6,17091779);ans=mul(rc(n),rc(m)); 
    42     for(rll l=1,r,s1,s2,s3;l<=n;l=r+1){
    43         r=Min(n/(n/l),m/(m/l));
    44         s1=mul(mul(n,m),r-l+1);
    45         s2=mul(mul(m/l,n/l),sumn2(r)-sumn2(l-1)+p);
    46         s3=mul(mol(mul(n/l,m)+mul(m/l,n)),sumsl(l,r));
    47         ans=mol(ans-mol(s1+s2-s3));
    48     } 
    49     printf("%lld",ans);
    50     return 0;
    51 }
    52 //19940417= 2848631*7 phi(19940417)=17091779
    View Code
  • 相关阅读:
    Silverlight2 开发环境 安装程序顺序
    Java——IO流超详细总结
    【慢慢学Android】:2.SharedPreferences对数据的存储
    【慢慢学算法】:求最大公约数
    【慢慢学算法】:求较大素数 筛选法
    【慢慢学算法】:排名
    手把手教你将vim配置成一个C/C++的超级IDE
    【慢慢学算法】:特殊乘法
    【慢慢学算法】:qsort()与sort的用法(收藏)
    【慢慢学算法】:数字阶梯求和
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/11652334.html
Copyright © 2011-2022 走看看