TJU Super Square

13 篇文章 0 订阅

If N Ns are added together, we know that it's the square of N. Well, if N Ns are multiplied together, we call it a super square of N. For example, the square of 3 is 3+3+3=9, while the super square is 3*3*3=27. It is quite easy for you, a clever programming fan, to calculate the super square of integers. Am I right?

Input

The input consists of several lines, each line contains an integer N (0 < N < 108). Input is terminated by N=0.

Output

For each test case, print a line with a single integer, which is the remainder of N's super square divides 2006 (the N's super square MOD 2006).

Sample Input

2
3
4
0

Sample Input

4
27
256 



题意概述:本题要求输出  N  的  N  次幂  模  2006  的结果。如上例中,当输入为3时,要求输出 3*3*3 % 2006 。

解题思路:本题主要用到数论中的同余知识,即  若 A%m=B%m ,则 A的n次幂%m  =  B的n次幂%m  。如此,即可将大于2006的数的                     运算转化为比2006小的数的运算。但是要注意,即使小于2006,但当N很大时,要求N次乘法运算,这样的话程序会超                         时。分析题意可知,任何一个数 %2006必是一个在0-2005之间的数,即在2007次运算后必然会出现重复的数字,即出现                       了循环节,如此便将循环的次数控制在2006次左右。

源代码:

#include<iostream>
#include<algorithm>
#include<deque> 
using namespace std;
int main()
{
    int N;                      
    deque<int>Set;          //该集合用来存放已经出现过的余数 
    deque<int>::iterator pos; //迭代器,搜寻 
    
    while(cin>>N&&N)
    {
         int result,factor,len,time;  
         if(N%2006==0)result=0;       //特殊情况 
         else
         {
             result=N%2006;
             factor=result;
             Set.push_back(result);    //一次幂时的余数 
             for(int i=2;i<=N;++i)
             {
                  result=result*factor%2006;
                  pos=find(Set.begin(),Set.end(),result); //查找result是否已经存在 
                  if(pos!=Set.end()){                      //存在 
                                     len=distance(pos,Set.end());//计算循环节的长度 
                                     time=(N-i+1)%len;           //求模 
                                     if(time==0)pos=Set.end()-1;  //若正好是循环节长度的n倍,则是循环节的最后一个元素 
                                     else advance(pos,time-1);    //否则 将pos向后移动time-1个 
                                     result=*pos;                  
                                     break;                       //终止循环 
                  }
                  else  Set.push_back(result);                    //若不存在,则将此次计算结果插入Set后 
             }
             Set.clear();                                         //清空Seg,避免影响下一次输入 
         }
         cout<<result<<endl;
    }
    return 0;



//当N>2006时一定会有循环节出现 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值