CF 359C Prime Number 暴力

来源:互联网 发布:电脑磁盘数据恢复 编辑:程序博客网 时间:2024/05/24 00:28
题意:式子:1/x^a[1] +1/x^a[2]....+1/x^a[n]=s/t. 给出x和序列a. 问gcd(s,t)模1e9+7 ?
n<=1e5, 2<=x<=1e9 , 0=<a[i]<=1e9. x为素数


题目给的x是素数。。。。。

分子底数相同 指数不同.  sum=a[1]+a[2]+..a[n] . f[i]=sum-a[i]
用优先队列直接写了个大暴力O(nlogn): 把x^f[1]+x^f[2]+...x^f[n] 一直合并 直到不能合并时 提取出此时最小的x^k即为gcd.

#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<ll,ll> ii;const ll mod=1e9+7;const int N=2e5+5;ll a[N],n,X,sum=0,f[N],m=0;vector<ii> v,x,y;ll powmod(ll x,ll n){ll s=1;while(n){if(n&1)s=(s*x)%mod;n>>=1;x=(x*x)%mod;}return s;}priority_queue<ii> q;ll solve(ll b){for(int i=0;i<x.size();i++)q.push(ii(-x[i].first,x[i].second));while(!q.empty()){ii t=q.top();q.pop();ll cnt=t.second,pw=0;while(!q.empty()&&q.top().first==t.first)cnt+=q.top().second,q.pop();while(cnt%b==0)cnt/=b,pw++;if(pw==0)return (-t.first);q.push(ii(-(-t.first+pw),cnt));}}int main(){ios::sync_with_stdio(false);cin.tie(0);cin>>n>>X;for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];for(int i=1;i<=n;i++)f[i]=sum-a[i];sort(f+1,f+1+n);for(ll i=1,j=1;i<=n;i=j){while(j<n&&f[j]==f[j+1])j++;x.push_back(ii(f[j],j-i+1));j++;}ll ans=1,pw=min(solve(X),sum);ans=(ans*powmod(X,pw))%mod;cout<<ans<<endl;return 0;}


标程的思路也是类似 不过模拟起来比上面简单多了。。 指数从大到小 每次合并后面相同的元素 若cnt%x==0 则将cnt/x个元素指数+1,否则指数无法再增加
#include <iostream>#include <vector>#include <cstdio>#include <algorithm>using namespace std;typedef long long li;const li MOD = 1000000007;li bpow(li x, li v) {if (v == 0)return 1 % MOD;if (v % 2 == 1)return (x * bpow(x, v - 1)) % MOD;li r = bpow(x, v / 2);return (r * r) % MOD;}int main() {int n, x;cin >> n >> x;vector < li > a(n), b;li sum = 0;for(int i = 0; i < n; i++) {cin >> a[i];sum += a[i];}for(int i = 0; i < n; i++) b.push_back(sum - a[i]);sort(b.rbegin(), b.rend());                 while (true) {li v = b[b.size() - 1];        int cnt = 0;while (b.size() > 0 && b[b.size() - 1] == v) {cnt ++;b.pop_back();}                if (cnt % x != 0) {                        v = min(v, sum);cout << bpow(x, v) << endl;return 0;}else {cnt /= x;for(int i = 0; i < cnt; i++) b.push_back(v + 1);}}}