Cod sursa(job #757487)

Utilizator vladiiIonescu Vlad vladii Data 12 iunie 2012 11:43:03
Problema Suma divizorilor Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define mod 9901
#define pb push_back
#define mkp make_pair

int A, B;
vector< pair<int, int> > divz;

void gcd(int &x, int &y, int a, int b)  {
     if (!b)
         x = 1, y = 0;
     else {
         gcd(x, y, b, a % b);
         int aux = x;
         x = y;
         y = aux - y * (a / b);
     }
}

int calc(int nr, int p) {
     if(p == 0) return 1;
     if(p == 1) return nr;

     int mid = p >> 1;

     int aux = calc(nr, mid);
     int ret = (aux * aux) % mod;
     if(p % 2 == 1) {
          ret = (ret * nr) % mod;
     }

     return ret;
}

int solve(int left, int right) {
     if(left == right) {
          int number = divz[left].first;
          int power = divz[left].second * B;

          int inv = 0, ins;
          gcd(inv, ins, number - 1, mod);
          if (inv <= 0) inv = mod + inv % mod;

          int put = calc(number, power+1) - number;
          while(put < 0) put += mod;

          put = (put * inv) % mod;

          return put;
     }

     int mid = (left + right) >> 1;

     int p1 = solve(left, mid);
     int p2 = solve(mid+1, right);

     return (p1 + p2 + p1 * p2) % mod;
}

int main() {
     FILE * f1= fopen("sumdiv.in", "r"), * f2 = fopen("sumdiv.out", "w");
     int i, j, p, q;

     fscanf(f1, "%d %d\n", &A, &B);

     int nA = A;
     for(i=2; i<=A; i++) {
          if(nA % i == 0) {
               int put = 0;

               while(nA % i == 0) {
                    put ++;
                    nA = nA / i;
               }

               divz.pb( mkp(i, put) );
          }
     }

     int sum = solve(0, divz.size()-1) + 1;

     fprintf(f2, "%d\n", sum % mod);

     fclose(f1); fclose(f2);
     return 0;
}