题意:已知X,数组arr[n],求一个分式的分子与分母的最大公因数。分子为ΣX^arr[i],分母为X^Σarr[i],数组为不递减序列。
思路:比赛的时候以为想出了正确思路,WA掉了很多发,看了别人写的代码才发现自己漏掉很多细节。
1.容易想到,分子的最低次幂即可能为所需答案
2.由于arr里存在相同的数,因此分子的各个幂存在可以合并同类项的情况,所以应该先彻底完成合并同类项,再进行步骤1。
3.一个小技巧,并不需要完成所有项的合并,当且仅当当前最小项的系数可以被X整除时才需要继续合并,否则当前项的次数即为答案所需次数。
特别需要注意的是:完成合并后,分子的最低次幂的次数是有可能大于分母的次数的,所以应该取二者的较小值作为答案的次数。
代码如下:
#include<cstdio> #include<iostream> using namespace std; const int mo=1e9+7; int x; int mpow(long long xx,long long nn){ long long res=1; while(nn!=0){ if(nn&1){ res=res*xx%mo; } nn>>=1; xx=xx*xx%mo; } return res; } int main(){ int n; long long num=0,arr[100010]; scanf("%d%d",&n,&x); for(int i=1;i<=n;i++){ scanf("%I64d",&arr[i]); num+=arr[i]; } for(int i=1;i<=n;i++){ arr[i]=num-arr[i]; } for(int i=1;i<=(n/2);i++){ swap(arr[i],arr[n-i+1]); } int sum=1; long long ans; arr[n+1]=-1; for(int i=2;i<=n+1;i++){ if(arr[i]==arr[i-1]){ sum++; } else { if(sum%x==0){ sum/=x; arr[--i]++; } else { ans=arr[i-1]; break; } } } ans=min(ans,num); printf("%d",mpow(x,ans)); return 0; }
By xxmlala
原文地址:https://www.cnblogs.com/xxmlala-fff/p/11622006.html
时间: 2024-10-17 04:02:35