神奇的结论题

首先,由于 g c d ( x , y ) l c m ( x , y ) = x y gcd(x,y)*lcm(x,y)=x*y gcd(x,y)lcm(x,y)=xy,然后有个结论小学就该知道了吧,乘积一定时,两个数差得越远和越大,所以,我们应该尽量多做这种操作。

考虑将 x , y x,y x,y质因数分解,设 x = p 1 a 1 p 2 a 2 p n a n x=p_1^{a_1} \cdot p_2^{a_2} \cdots p_n^{a_n} x=p1a1p2a2pnan y = p 1 b 1 p 2 b 2 p n b n y=p_1^{b_1} \cdot p_2^{b_2} \cdots p_n^{b_n} y=p1b1p2b2pnbn(若某个质因子不存在就让它的指数为零)。考虑gcd和lcm的本质,则 g c d ( x , y ) = p 1 m i n ( a 1 , b 1 ) p 2 m i n ( a 2 , b 2 ) p n m i n ( a n , b n ) gcd(x,y)=p_1^{min(a_1,b_1)} \cdot p_2^{min(a_2,b_2)} \cdots p_n^{min(a_n,b_n)} gcd(x,y)=p1min(a1,b1)p2min(a2,b2)pnmin(an,bn) l c m ( x , y ) = p 1 m a x ( a 1 , b 1 ) p 2 m a x ( a 2 , b 2 ) p n m a x ( a n , b n ) lcm(x,y)=p_1^{max(a_1,b_1)} \cdot p_2^{max(a_2,b_2)} \cdots p_n^{max(a_n,b_n)} lcm(x,y)=p1max(a1,b1)p2max(a2,b2)pnmax(an,bn),然后就可以发现,每次操作过后,指数小的往小的方向移动,指数大的往大的方向移动。

所以最终的状态,应该是所有质因子按指数从小到大的顺序排列。把每个数暴力分解,sort一波就好了…

#include <bits/stdc++.h>
#define ll long long
#define fr(i,x,y) for(int i=x;i<=y;i++)
#define rf(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const int N=100001;
const int p=1e9+7;
int n;
ll a[N];
map<ll,vector<int>> mp;

template<class T> void checkmin(T &a,const T &b) { if (b<a) a=b; } 
template<class T> void checkmax(T &a,const T &b) { if (b>a) a=b; }

class GCDLCM2 {
public:
    int getMaximalSum( vector <int> start, vector <int> d, vector <int> cnt ) ;
};

void deco(ll &x){
	int s=0;
	for(ll i=2;i*i<=x;i++)
	 if (x%i==0){
	 	s=0;
	 	while(x%i==0) x/=i,s++;
	 	mp[i].push_back(s);
	 }
	if (x>1) mp[x].push_back(1),x=1;
}

ll power(ll a,int n){
	ll ans=1;
	for(ll sum=a;n;n>>=1,sum=sum*sum%p) if (n&1) ans=ans*sum%p;
	return ans;
}

int GCDLCM2::getMaximalSum(vector <int> start, vector <int> d, vector <int> cnt) {
    for(int i=0;i<start.size();i++)
     for(int j=0;j<cnt[i];j++)
      a[++n]=start[i]+1ll*j*d[i];
    //fr(i,1,n) cout<<a[i]<<' ';
    fr(i,1,n) deco(a[i]);
    for(map<ll,vector<int>>::iterator it=mp.begin();it!=mp.end();it++){
    	vector<int> v=it->second;
    	sort(v.rbegin(),v.rend());
    	for(int i=0;i<v.size();i++)
    	 a[n-i]=a[n-i]*power(it->first,v[i])%p;
    	//cout<<it->first<<' ';
    }
    ll S=0;
    //cout<<endl;
    fr(i,1,n) S=(S+a[i])%p;
    return S;
}