ZJU 3061 Function

54 篇文章 0 订阅
该博客主要展示了如何用C语言实现ZJU 3061 Function的算法,包括pri函数用于处理数字的转换,ppow函数用于快速求幂运算。在main函数中,根据输入的n和k值,计算并输出特定条件下的结果。算法涉及到数论和位操作。
摘要由CSDN通过智能技术生成

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2715
题目意思很简单就是输入2个数n,k叫你求sigma(f(i))%k (1<=i<=n)
我的算法很明显不是最好的,跑了780MS+,不过在取mod时候稍微优化下应该是几百MS的级别吧...不说了下面说下思路

利用2的特点
扫描出现2,那么马上可以使循环变量直接跳:
如:
扫描到2000(3)的时候,那么直接下次就计算10000,因为2000~2222的结果完全一样
扫描到112000(3)的时候,那么下次就计算120000(3),因为112000~112222的结果仍然是一样,这样优化下就可以过了
比赛的时候偶是第一个AC的hihi~
  1. #include<iostream>
  2. using namespace std;
  3. int cnt,tot;
  4. int tmp[50];
  5. int pri(int n)
  6. {
  7.     int l=0,tn=n,i,tp=0;
  8.     while(n)
  9.     {
  10.         tmp[l++]=n%3;
  11.         n/=3;
  12.     }
  13.     for(i=l-1;i>=0;i--)if(tmp[i]==2)break;else tp=tp*3+tmp[i];
  14.     cnt=i;
  15.     tot=l-1;
  16.     if(i==-1)return tn;
  17.     if(i==l-1)return 0;
  18.     return tp;
  19. }
  20. int ppow(int a,int b)
  21. {
  22.     int ret=1;
  23.     for(;b;b>>=1,a*=a)if(b&0x1)ret*=a;
  24.     return ret;
  25. }
  26. int main()
  27. {
  28.     int i,n,ans,tm,c,k;
  29.     while(scanf("%d%d",&n,&k)!=EOF)
  30.     {
  31.         ans=0;
  32.         for(i=1;i<=n;i++)
  33.         {
  34.             tm=pri(i);
  35.             if(cnt==-1)
  36.                 ans+=tm;
  37.             else if(!tm)
  38.                 i=ppow(3,tot+1)-1;
  39.             else
  40.             {
  41.                 if(i+(c=ppow(3,cnt))>n)
  42.                     ans+=((n-i+1)%k)*(tm%k);
  43.                 else ans+=(c%k)*(tm%k);
  44.                 i+=c-1;
  45.             }
  46.             ans%=k;
  47.         }
  48.         printf("%d/n",ans);
  49.     }
  50.     return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值