Cod sursa(job #1820682)

Utilizator Kln1000Ciobanu Bogdan Kln1000 Data 2 decembrie 2016 01:03:09
Problema Suma si numarul divizorilor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.34 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>

#define mod 9973
#define MXP 1000010

using namespace std;

int64_t q;
vector <int> prim;

class iparser{
    public:
        iparser() {}
        iparser(const char *file_name){
            input_file.open(file_name);
            cursor=0;
            input_file.read(buffer,SIZE);}
        inline iparser &operator >>(int64_t &n){
            while(buffer[cursor]<'0' or buffer[cursor]>'9') inc();
            n=0;
            while('0'<=buffer[cursor] and buffer[cursor]<='9')
                n=n*10+buffer[cursor]-'0',inc();
            return *this;}
    private:
        ifstream input_file;
        static const int SIZE=0x8000;
        char buffer[SIZE];
        int cursor=0;
        inline void inc(){
            if(++cursor==SIZE)
                cursor=0,input_file.read(buffer,SIZE);
        }
};


int64_t pow(int64_t x,int64_t y)
{
    int64_t m=1;
    while(y)
    {
        if(y&1)
        {
            m=(m*x)%mod;
        }
        x=(x*x)%mod;
        y>>=1;
    }

    return m;
}

void ciuruieste()
{
    bitset <MXP> prime;
    for (int i=1;((i*i)<<1)+(i<<1)<MXP;++i)
        if(!prime[i])
            for(int j=((i*i)<<1)+(i<<1);(j<<1)+1<MXP;j+=(i<<1)+1)
                prime[j]=true;
    prim.push_back(2);
    for(int i=1;(i<<1)+1<MXP;++i)
        if(!prime[i])
            prim.push_back((i<<1)+1);
}

vector < pair<int,int> > decompose(int64_t target){
    vector < pair<int,int> > aux;
    int how_many,target1=target;
    for (auto i:prim)
        if (target%i==0){how_many=0;
            while (target%i==0){target/=i;++how_many;}
        aux.push_back({i,how_many});
        target=target1;
    }
    return aux;
}

    ofstream t ("ssnd.out");

void solve(int64_t target){
    vector < pair<int,int> > w=decompose(target);
    int64_t how_many=1,sum=1;
    for (auto i:w){
        how_many*=(1+i.second);
        sum=(1LL*sum*(pow(i.first,i.second+1)-1)/(i.first-1))%mod;
    }
    if (target!=1){
        if (how_many==1)
            ++how_many;
        if (sum==1)
            sum+=target;}
    t<<how_many<<" "<<sum<<'\n';
    }

int main()
{
    iparser f ("ssnd.in");
    int64_t aux;
    ciuruieste();
    f>>q;
    for (;q;--q)
        f>>aux,solve(aux);
    return 0;
}