iwtgm-12

补G题
一个大模拟
首先p不一定是质数,不能用逆元,用到了杨辉三角处理二次项系数
首先输入就很唬人,看题解学到用标记的方式分隔
系数默认为1,幂默认为1
有两个字符变量相同的情况,把系数合并
系数不为0才输出,系数为1不输出1,非1才有乘号,幂为1不输出
t次方就是杨辉三角的第t行,0-t就是从左到右的二次项系数,第一个变量和系数的幂次是t-i,第二个是i

ll p,t;//模数、幂
string vv[2];//两个字母变量
ll x[2];//两个系数
string s;//输入字符串
ll C[N][N];//杨辉三角得到二次项系数,因为p不一定为质数,所以不能用逆元,用杨辉三角
void init(){
    C[0][0]=1;
    for(int i=1;i<N;i++){
        C[i][0]=1;
        for(int j=1;j<=i;j++){
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
        }
    }
}
ll ksm(ll a,ll b){
    a%=p;
    ll res=1;
    while(b){
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
void solve(){
    cin>>s;
    int zt=0;//标记,用来处理字符串
    x[0]=x[1]=1;//系数默认为1
    t=1;//幂默认为1
    string tmp="";//字母变量
    ll a=0;//字符串->数字用
    for(int i=0;i<s.size();i++){
        if(s[i]=='('){
            zt=1;//此时处理第一个系数
        }else if(s[i]=='+'){
            zt=2;//此时处理第二个系数
        }else if(s[i]==')'){
            zt=3;
        }else if(s[i]=='^'){
            zt=4;//此时处理幂
        }else if(s[i]=='%'){//%一定出现
            if(a){//有幂则更新幂
                t=a;
                a=0;
            }
            zt=5;//处理模数
        }else{
            if(zt==1){
                if(s[i]>='0'&&s[i]<='9'){
                    a=a*10+(s[i]-'0');
                }else{
                    if(a){//a为系数
                        x[0]=a;
                    }
                    a=0;
                    tmp+=s[i];
                    vv[0]=tmp;//第一个字符变量
                    tmp="";
                }
            }else if(zt==2){
                if(s[i]>='0'&&s[i]<='9'){
                    a=a*10+(s[i]-'0');
                }else{
                    if(a){//第二个系数
                        x[1]=a;
                    }
                    a=0;
                    tmp+=s[i];
                    vv[1]=tmp;//第二个字符变量
                    tmp="";
                }
            }else if(zt==4){
                if(s[i]>='0'&&s[i]<='9'){
                    a=a*10+(s[i]-'0');
                }
            }else if(zt==5){
                if(s[i]>='0'&&s[i]<='9'){
                    a=a*10+(s[i]-'0');
                }
            }
        }
    }
    p=a;//得到模数
    init();//杨辉三角
    if(vv[0]==vv[1]){//两个字符变量相同,则把系数合并
        ll xx=(x[0]+x[1])%p;
        vector<ll>v;
        ll now=ksm(xx,t)%p;
        if(now){//系数不为0
            v.push_back(now);
        }
        if(v.size()==0){//系数为0,不输出
            cout<<s<<" = "<<"0";
        }else{
            cout<<s<<" = ";
            if(now!=1)//系数为1,1不输出
                 cout<<now<<"*";
            cout<<vv[0];
            if(t!=1){//幂为1,1不输出
                cout<<"^"<<t;
            }
            cout<<"%"<<p;
        }
        return ;
    }
    vector<pair<ll,pair<int,int>>>v;
    for(ll i=0;i<=t;i++){//t次方就是杨辉三角的第t行,0-t就是从左到右的二次项系数,第一个变量和系数的幂次是t-i,第二个是i
        ll now=C[t][i]*ksm(x[0],t-i)%p*ksm(x[1],i)%p;//二次项系数*变量系数
        if(now!=0){//系数不为0才要输出
            v.push_back({now,{t-i,i}});//存下要输出的系数、幂次
        }
    }
    if(v.size()==0){//系数全为0,不输出
        cout<<s;
        cout<<" = ";
        cout<<"0";
    }else if(v.size()==1){//只有一项,没有括号
        cout<<s;
        cout<<" = ";
        int fg=0;
        if(v[0].first!=1){
            cout<<v[0].first;
            fg=1;//系数不为0
        }
        if(v[0].second.first){
            if(fg==1){//系数不为0,才有乘号
                cout<<"*"<<vv[0];
            }else{
                cout<<vv[0];
            }
            fg=1;
            if(v[0].second.first!=1){//幂次不为1才有"^"
                cout<<"^"<<v[0].second.first;
            }
        }
        if(v[0].second.second){//同理
            if(fg==1){
                cout<<"*"<<vv[1];
            }else{
                cout<<vv[1];
            }
            fg=0;
            if(v[0].second.second!=1){
                cout<<"^"<<v[0].second.second;
            }
        }
        cout<<"%"<<p;
    }else{//多项,有括号
        cout<<s;
        cout<<" = ";
        cout<<"(";
        int tot=0;
        for(auto i:v){
            int fg=0;
            if(i.first!=1) {
                cout << i.first;
                fg=1;
            }
            if(i.second.first){
                if(fg==1){
                    cout<<"*"<<vv[0];
                }
                else{
                    cout<<vv[0];
                }
                fg=1;
                if(i.second.first!=1){
                    cout<<"^"<<i.second.first;
                }
            }
            if(i.second.second){
                if(fg==1){
                    cout<<"*"<<vv[1];
                }
                else{
                    cout<<vv[1];
                }
                fg=0;
                if(i.second.second!=1){
                    cout<<"^"<<i.second.second;
                }
            }
            if(tot!=v.size()-1){
                cout<<"+";
            }
            tot++;
        }
        cout<<")";
        cout<<"%"<<p;
    }
}
posted @ 2023-11-03 22:13  WW爆米花  阅读(7)  评论(0编辑  收藏  举报