Cod sursa(job #2128098)

Utilizator arcoC. Nicolae arco Data 11 februarie 2018 14:04:43
Problema Suma divizorilor Scor 60
Compilator c Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <math.h>
 
typedef unsigned int uint;
 
#define M 9901
 
void fact(int64_t a, int64_t b, FILE *out);
int64_t binexp(int64_t x, int64_t n);
int64_t egcd(int64_t a, int64_t b, int64_t *x, int64_t *y);
int64_t inv(int64_t a, int64_t m);
int64_t count_div(int64_t n);
 
int main(void)
{
    FILE *in =  fopen("sumdiv.in", "r");
	FILE *out = fopen("sumdiv.out", "w");
 
    if(in != NULL && out != NULL)
    {
        int64_t a, b;
        fscanf(in, "%lld%*c%lld", &a, &b);
        if(a == 0)
        {
        	fprintf(out, "0");
        	return 0;
        }
        if(b == 0)
        {
        	fprintf(out, "%lld\n", count_div(a));
			return 0;        	
        }
        fact(a, b, out);
 
        fclose(in);
        fclose(out);
    }
    else
    {
        printf("file error\n");
    }
 
    return 0;
}

int64_t count_div(int64_t n)
{
	int64_t d = 2, count = 1;
	while(n > 1)
	{
		int64_t p = 0;
		while(n % d == 0)
		{
			p++;
			n /= d;
		}
		if(p)
		{
			count = ((count % M) * ((p + 1) % M)) % M;
		}
		d++;
		if(n > 1 && d * d > n)
		{
			d = n;
		}
	}
	return count;
}
 
int64_t inv(int64_t a, int64_t m)
{
    int64_t x, y;
    int64_t d = egcd(a, m, &x, &y);
    if(d == 1)
    {
        return ((x % m) + m) % m;
    }
    else
    {
        printf("No invers moduloar\n");
    }
}
 
int64_t egcd(int64_t a, int64_t b, int64_t *x, int64_t *y)
{
    if(a == 0)
    {
        *x = 0;
        *y = 1;
        return b;
    }
    else
    {
        int64_t x1, y1;
        int64_t d = egcd(b % a, a, &x1, &y1);
        *x = y1 - (b / a) * x1;
        *y = x1;
        return d;
    }
}
 
int64_t binexp(int64_t x, int64_t n)
{
    int64_t res = 1;
    while(n)
    {
        if(n % 2 != 0)
        {
            res = ((res % M) * (x % M)) % M; 
        }
        x = ((x % M) * (x % M)) % M;
        n /= 2;
    }
    return res;
}
 
void fact(int64_t a, int64_t b, FILE *out)
{
    int64_t s = 1;
    int64_t d = 2;
    while(a > 1)
    {
        int64_t p = 0;
        while(a % d == 0)
        {
            p++;
            a /= d;
        }
        if(p)
        {
            p *= b;
            int64_t calc = (((binexp(d, p + 1) - 1) % M) * (inv(d - 1, M))) % M;
            s = ((s % M) * (calc % M)) % M;
        }
        d++;
        if(a > 1 && d * d > a)
        {
            d = a;
        }
    }
    fprintf(out, "%lld\n", s);
}