部分問題への分割
基本にのっとって問題の分割をすると、再帰的な問題だと気づく
まさか解法が降ってくるとは思わなかった
- #include<iostream>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #define lol(i,n) for(int i=0;i<n;i++)
- #define mod 1000000007
- typedef long long ll;
- using namespace std;
- ll Pmod(ll n,ll k){
- ll r=k,ret=1;
- while(true){
- if(n==0)break;
- if(n%2==1){
- ret=ret*r%mod;
- }
- n/=2;
- r=r*r%mod;
- }
- return ret;
- }
- vector<pair<ll,ll> > v;
- int main(){
- ll n,k;
- cin>>n>>k;
- for(ll i=1;i*i<=n;i++){
- if(n%i==0){
- v.push_back(make_pair(i,-1));
- if(i!=n/i)v.push_back(make_pair(n/i,-1));
- }
- }
- sort(v.begin(),v.end());
- ll ans[2]={0,0};
- for(int i=0;i<v.size();i++){
- ll x=v[i].first;
- ll tmp=Pmod((x+1)/2,k);
- for(int j=0;j<i;j++){
- if(x%v[j].first==0){
- tmp=(mod+tmp-v[j].second)%mod;
- }
- }
- v[i].second=tmp;
- ans[x%2]+=tmp*x%(mod*(ll)10);
- }
- //cout<<ans[0]<<" "<<ans[1]<<endl;
- cout<<(ans[0]/2+ans[1])%mod<<endl;
- return 0;
- }
後で割る時は、modで抑えるといけないのでmodを5倍くらいにしとく