Cod sursa(job #132006)

Utilizator mariusdrgdragus marius mariusdrg Data 4 februarie 2008 20:58:51
Problema Eval Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.66 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;
int val[400];
int pr[200];

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]; ++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;
}

void nrpr()
{
        int i,j;
        int maxi = 2000000000;
        int nrp = 110;
        for (i = maxi;pr[0] <= nrp; ++i)
        {
                if (i % 2 == 0) continue;
                int ver = 1;
                for(j = 3;(long long)j * j <= i; ++j)
                {
                        if (i % j == 0)
                        {
                                ver = 0;
                                break;
                        }
                }
                if (ver) pr[++pr[0]] = i;
        }
}


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]);
        }

        nrpr();

        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;
}