Cod sursa(job #132024)

Utilizator mariusdrgdragus marius mariusdrg Data 4 februarie 2008 21:26:51
Problema Eval Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.34 kb
#include<stdio.h>
#include<algorithm>


int expr();
int factor();
int getnumber();
int termen();

typedef int lnum[11000];

int i;
const int baz = 10000;
int n;
lnum rez,aux,prod;
char s[101000];
int p;
int mod;
const int pr[200] = {111,2000000011,2000000033,2000000063,2000000087,2000000089,2000000099,2000000137,2000000141,2000000143,2000000153,2000000203,2000000227,2000000239,2000000243,2000000269,2000000273,2000000279,2000000293,2000000323,2000000333,2000000357,2000000381,2000000393,2000000407,2000000413,2000000441,2000000503,2000000507,2000000531,2000000533,2000000579,2000000603,2000000609,2000000621,2000000641,2000000659,2000000671,2000000693,2000000707,2000000731,2000000741,2000000767,2000000771,2000000773,2000000789,2000000797,2000000809,2000000833,2000000837,2000000843,2000000957,2000000983,2000001001,2000001013,2000001043,2000001049,2000001089,2000001097,2000001103,2000001109,2000001119,2000001127,2000001137,2000001149,2000001151,2000001167,2000001173,2000001187,2000001229,2000001233,2000001247,2000001257,2000001277,2000001287,2000001349,2000001359,2000001379,2000001413,2000001457,2000001511,2000001517,2000001527,2000001539,2000001551,2000001557,2000001583,2000001599,2000001623,2000001629,2000001649,2000001677,2000001727,2000001743,2000001821,2000001833,2000001851,2000001881,2000001929,2000001953,2000001973,2000002031,2000002061,2000002091,2000002129,2000002133,2000002153,2000002171,2000002177,2000002183,2000002217,2000002259};

int val[400];

int r[200];

void imp(lnum &dest,int a)
{
        long long te = 0,i;
        for(i = dest[0];i;--i)
        {
                te = (long long) te * baz + dest[i];
                dest[i] = te / a;
                te =(long long) te % a;
        }
        while(dest[dest[0]] == 0)dest[0]--;
}

void print(lnum &s)
{
        int i;
        printf("%d",s[s[0]]);
        for(i = s[0] - 1;i >= 1; --i) printf("%.4d",s[i]);
        printf("\n");
}

void ad(lnum &dest,lnum &s,lnum &s1)
{
        int te = 0,i;
        for(i = 1;i <= s[0] || i <= s1[0] || te; ++i)
        {
                te += s[i] + s1[i];
                dest[i] = te % baz;
                te /= baz;
        }
        dest[0] = i - 1;
}

void inmul(lnum &s,int nr)
{
        long long i,te = 0;
        for(i = 1;i <= s[0] || te; ++i)
        {
                te = ((long long)te + (long long)s[i] * nr);
                s[i] = (long long)te % baz;
                te /= baz;
        }
        s[0] = i - 1;

}

int expr()
{
        int ret = termen();
        while(s[p] == '+' || s[p] == '-')
        {
                ++p;
                if (s[p - 1] == '+')ret = ((long long) ret + termen()) % mod;
                if (s[p - 1] == '-')ret = ((long long) ret - termen()) % mod;
                
        }
        ++p;
        return ret;
}

int termen()
{
        int ret = factor();
        while(s[p] == '*')
        {
                ++p;
                ret = ((long long)ret * factor()) % mod;
        }
        return ret;
}

int factor()
{
        int ret = 1;
        while(s[p] == '+' || s[p] == '-')
        {
                ret *= (s[p] == '+' ? 1 : -1);
                ++p;
        }
        if (s[p] == '(')
        {
                ++p;
                return ret * expr();
        }
        if (s[p] == '[')
        {
                ++p;
                int te = expr();
                te = ((long long)  te * te) % mod;
                return ret * te;
        }
        ++p;
        return ret * val[s[p - 1]];
}

int gcd(int a,int b,int &x,int &y)
{
        if (b == 0)
        {
                x = 1;
                y = 0;
                return 0;
        }
        int x0,y0;
        gcd(b,a % b,x0,y0);
        x = y0;
        y = x0 - (a / b) * y0;
        return 0;
}

long long modu(lnum &s,int a)
{
        long long te = 0,i;
        for(i = s[0]; i; --i)
        {
                te = (long long)te * baz + s[i];
                te %= a;
        }
        return te;
}

void scad(lnum &s,lnum&s1)
{
        int i,te = 0;
        for(i = 1;i <= s[0]; ++i)
        {
                te += s[i] - s1[i];
                s[i] = (baz + te) % baz;
                if (te < 0) te = -1;
                   else te = 0;
        }
        while(s[s[0]] == 0) --s[0];
}


bool cmp(lnum &s,lnum &s1)
{
        int i;
        if (s[0] != s1[0]) return s[0] > s1[0];
        for(i = s[0]; i;--i)
        {
                if (s[i] != s1[i]) return s[i] > s1[i];
        }
        return 1;
}


int main()
{
        freopen("eval.in","r",stdin);
        freopen("eval.out","w",stdout);
        scanf("%d",&n);
        int i = 0;
        for(i = 1;i <= n; ++i)
        {
                scanf("%d\n",&val['a' + i - 1]);
        }

        scanf("%s",s);


        for(i = 1;i <= pr[0]; ++i)
        {
                mod = pr[i];
                p = 0;
                r[i] = expr();
        }

        prod[prod[0] = 1] = 1;

        for(i = 1;i <= pr[0]; ++i)
        {
                inmul(prod,pr[i]);
        }
        for(i = 1;i <= pr[0]; ++i)
        {
                int x = 0,y = 0;
                imp(prod,pr[i]);
                gcd(pr[i],modu(prod,pr[i]),x,y);
                if (y < 0) y += pr[i];
                memcpy(aux,prod,sizeof(prod));
                inmul(aux,y);
                inmul(aux,r[i]);
                ad(rez,rez,aux);
                inmul(prod,pr[i]);
        }

        while(cmp(rez,prod))scad(rez,prod);
        print(rez);
        


        return 0;
}