2015ACM-ICPC 北京赛区 Problem K. A Math Problem

来源:互联网 发布:php 表单数据提交 编辑:程序博客网 时间:2024/05/21 09:57
Description 
 Stan is crazy about math. One day, he was confronted with an interesting integer function defined on positive integers, which satisfies f(1) = 1 and for every positive integer n, 3× f(n) × f(2n+1) = f(2n) × (1 + 3f(n)), f(2n) < 6×f(n).  He wanted to know, in the range of 1 to n, for a given k, what are f(i) mod k like. For simplicity, you could just calculate the number of i which satisfies f(i) mod k = t for every t in range of 0 to k – 1 as g(t), and tell Stan what is all g(x) xor up is. 
Input 
 There are no more than 40 test cases.  The first line of the input contains an integer T which means the number of test cases.  Each test case contains two integer, n, k, just as mentioned earlier. Please note that n ≤ 1018, and k is a known Fermat prime -- that is to say, k is among { 3,5,17,257,65537} .  
Output 
 
For each test case, output the result of all g(x) xor up. 
Sample Input 
2 1 3 5 5 
Sample Output 

1 3 


题目大意:

有个函数满足

3× f(n) × f(2n+1) = f(2n) × (1 + 3f(n)), f(2n) < 6×f(n)

且f(2n)<6*f(n)

输入n和k

另g(x)为f(n)%k==x的个数

x为0到k-1之间

求g(x)的异或和



因为有个小于号限定

所以f(2n)=3*f(n)

f(2n+1)=3*f(n)+1

然后我们可以迭代

设fx(n)为处理函数

对于n为偶数

则处理fx(n/2),然后将其中的余数*3和*3+1求出fx(n)

若n为奇数

则迭代fx(n-1)再暴力求出f(n)即可

P,S 因为没找到评测的地方所以正确性不保证

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

update:在hiho上交了。过了

<pre name="code" class="cpp">#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int k;long long sx[65537],tsx[65537];inline int cale(long long n){if(n==1)return 1;else if(n%2==1)return (3*cale((n-1)/2)+1)%k;elsereturn 3*cale(n/2)%k;}inline void fx(long long n){if(n==1){sx[1]=1;return ;}int i;if(n%2==0){fx(n/2);memset(tsx,0,sizeof(tsx));for(i=0;i<=k-1;i++){tsx[i*3%k]+=sx[i];tsx[(i*3+1)%k]+=sx[i];}for(i=0;i<=k-1;i++)sx[i]=tsx[i];sx[1]++;sx[cale(n+1)]--;}else{fx(n-1);sx[cale(n)]++;}}int main(){freopen("k.in","r",stdin);freopen("k.out","w",stdout);int T;scanf("%d",&T);while(T>0){T--;int i;long long n;scanf("%lld%d",&n,&k);memset(sx,0,sizeof(sx));fx(n); long long ans=0;for(i=0;i<=k-1;i++)ans=(ans^sx[i]);//for(i=0;i<=k-1;i++)//printf("%lld ",sx[i]);//printf("\n");printf("%lld\n",ans);}return 0;}


                                             
0 0