• 【UVA1635】哑元


    题意

    给定n个数a1,a2,...an,依次求出相邻两数之和,将得到一个新数列。重复上述操作,最后结果将变成一个数。问这个数除以m的余数与哪些数无关?例如n=3,m=2时,第一次求和得到a1+a2,a2+a3,再求和得到a1+2a2+a3,它除以2的余数和a2无关。(1 ≤ n ≤ 100 000, 2 ≤ m ≤ 109 )

    分析

    举的这个例子已经疯狂暗示了,怎么看都是二项式定理啊!!!

    二项式定理就不写了,反正就是求组合数了,有一个递推的式子

    证明太显然了,直接拆成递推形式一眼就看出来了。于是可以利用它计算出C(n-1,i-1)的每一项,得到ai的系数,再判断一下是不是m的倍数

    直接递推太大了,会涉及到高精,于是利用唯一分解定理分解m,再比较各个质因子的指数与C(n-1,i-1)中的指数即可。

    代码

    1. #include<bits/stdc++.h>  
    2. using namespace std;  
    3. #define N 100010  
    4. int n,m,cnt;  
    5. int p[N],c[N],ok[N];  
    6. vector<int>ans;  
    7. void divide(int k)  
    8. {  
    9.     cnt=0;  
    10.     memset(p,0,sizeof(p));  
    11.     memset(c,0,sizeof(c));  
    12.     int mx=(int)sqrt(k+1);  
    13.     for(int i=2;i<=mx;i++)  
    14.     {  
    15.         if(k%i==0)  
    16.         {  
    17.             p[++cnt]=i;  
    18.             while(k%i==0)c[cnt]++,k/=i;  
    19.         }  
    20.         if(k==1)break;  
    21.     }  
    22.     if(k>1)p[++cnt]=k,c[cnt]=1;   
    23. }  
    24.   
    25. vector<int> solve()  
    26. {  
    27.     memset(ok,-1,sizeof(ok));  
    28.     vector<int>v;n--;  
    29.     for(int i=1;i<=cnt;i++)  
    30.     {  
    31.         int cm=0;  
    32.         for(int k=1;k<n;k++)  
    33.         {  
    34.             int a=n-k+1,b=k;  
    35.             while(a%p[i]==0)a/=p[i],cm++;  
    36.             while(b%p[i]==0)b/=p[i],cm--;  
    37.             if(cm<c[i])ok[k]=0;  
    38.         }  
    39.     }  
    40.     for(int i=1;i<n;i++)if(ok[i])v.push_back(i+1);  
    41.     return v;  
    42. }  
    43.   
    44. int main()  
    45. {  
    46.     while(scanf("%d%d",&n,&m)==2)  
    47.     {  
    48.         divide(m);  
    49.         ans=solve();  
    50.         printf("%d ", (int)ans.size());  
    51.         for (int i = 0; i < ans.size(); i++)   
    52.             printf("%d%c",ans[i],i==ans.size()-1?' ':' ');  
    53.         if (ans.size()==0) printf(" ");   
    54.     }  
    55.     return 0;  
    56. }  
  • 相关阅读:
    线程阶段性总结——APM,ThreadPool,Task,TaskScheduler ,CancellationTokenSource
    研究BackgroundWorker后发现:AsyncOperation和SynchronizationContext的差异真的很大!
    线程同步——优势、劣势
    APM异步编程模型的优势
    DataGridView的VirtualMode,在大容量数据加载时特别有用
    【C】——C语言的位运算的优势
    【linux】——Linux tar打包命令
    【C】用文件和链表实现学生信息管理
    【C】——回调函数的好处
    【C】strcpy()需谨慎使用;
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9865529.html
Copyright © 2020-2023  润新知