1. 程式人生 > >UVA1635 Irrelevant Elements

UVA1635 Irrelevant Elements

個數 過程 int 唯一分解定理 個數字 cst 如果 題解 ant

題意:給定一個序列,依次求出相鄰兩個數字的和,將得到一個新序列,重復上述過程直到最後的結果是是一個數。求最後的數除m的余數和原序列中的那些數無關。

題解:模擬可以得出最後一個數是原序列的線性和。沒一項的系數恰好滿足楊輝三角的規律。C(k,n)=(n-k+1)/k*C(k-1,m)。用這個可以0(n)的復雜度推出系數。但是由於數據很大,如果直接推的話,要用大數處理,過於麻煩。考慮到這裏只關心那些系數是m的倍數,對於很大的數我們可以用唯一分解定理,把他以素數因子指數的形式處理,而且指數的關系是可以通過C(k,n)=(n-k+1)/k*C(k-1,m)這個關系式遞推的。

ac代碼:

#include <cstdio>
#include 
<iostream> #include <cstring> #include <queue> using namespace std; int n,m; int prime[10001]; int e[10001]; int c[100001]; int init()// 唯一分解定理 { int ret=0; for(int i=2;i*i<=m;i++) { if(m%i==0) { prime[ret]=i; while(m%i==0) { e[ret]
++; m/=i; } ret++; } } if(m>1) { prime[ret]=m; e[ret++]++; } return ret; } int e2[100001]; int check(int len) { for(int i=0;i<len;i++) { if(e2[i]<e[i]) return 0; } return 1; } int main() {
while(cin>>n>>m) { // cout<<sum<<endl; memset(e,0,sizeof(e)); int ret=0; queue<int> out; memset(c,0,sizeof(c)); memset(e2,0,sizeof(e2)); int sum=init();// c[0]=1; for(int i=1;i<n;i++) { int temp=n-1-i+1;// 對應n為多少要理清楚 int zz=i; // cout<<temp<<‘ ‘<<zz<<endl; for(int j=0;j<sum;j++)// 遞推指數關系的時候,由於有除法,可能出限小數,所以我們分子,分母分開處理 { if(temp%prime[j]==0) { while(temp%prime[j]==0) { e2[j]++; temp=temp/prime[j]; // cout<<1<<endl; } } if(zz%prime[j]==0) { while(zz%prime[j]==0) { e2[j]--; zz=zz/prime[j]; // cout<<2<<endl; } } } if(check(sum)) { ret++; out.push(i+1); } } cout<<ret<<endl; if(ret!=0) { cout<<out.front(); out.pop(); } while(!out.empty()) { cout<< <<out.front(); out.pop(); } cout<<endl; } return 0; }

UVA1635 Irrelevant Elements