Advertisement

【CodeChef】Just multiply

阅读量:

该文本讨论了如何高效地进行大数运算(如模运算)以及如何优化快速幂算法的实现方式。涉及的内容包括:
模运算:通过mul和Pow等函数实现高效的乘法和幂次计算。
字符串处理:将字符串中的数字提取并用于计算。
快速幂算法:通过位操作优化幂次计算的速度。
模指数循环节:探讨如何避免直接取模导致的性能问题,并提供了解决方案。
这些内容的核心在于优化大数运算效率,并在实际应用中减少直接取模带来的性能损失。

数据水

讲道理,指数循环节不能直接取模

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 char inc;
    
 inline void get(int& x)
    
 {
    
 	x = 0;inc = getchar();
    
 	while(!isdigit(inc))inc=getchar();
    
 	while(isdigit(inc))
    
 	{
    
 		x=x*10+inc-'0';
    
 		inc=getchar();
    
 	}
    
 }
    
 #define maxn 10010
    
 int T,mod,len;typedef long long ll;
    
 char s[maxn];
    
 ll mul(ll x,ll p)
    
 {
    
 	if(x==0)return 0;
    
 	if(p==0)return 1;
    
 	ll t = x,ret=1;
    
 	while(p)
    
 	{
    
 		if(p&1)ret*=t;
    
 		t*=t;
    
 		t%=mod;
    
 		ret%=mod;
    
 		p>>=1;
    
 	}
    
 	return ret;
    
 }
    
 int main()
    
 {
    
 	get(T);	
    
 	while(T--)
    
 	{
    
 		get(mod);scanf("%s",s);
    
 		len = strlen(s);
    
 		ll last = 1;bool flag = false;
    
 		ll fir = 0,sec = 0;
    
 		for(int i=0;i<len;i++)
    
 		{
    
 			if(s[i]!='*')
    
 			{
    
 				if(!flag)fir = (fir*10+s[i]-'0')%mod;			
    
 				else sec = (sec*10+s[i]-'0')%mod;
    
 			}
    
 			else
    
 			{
    
 				if(s[i+1]=='*')
    
 				{
    
 					i=i+1;
    
 					flag = true;					
    
 				}
    
 				else 
    
 				{
    
 					if(flag)
    
 					{			
    
 						last = last*(mul(fir,sec)%mod)%mod;
    
 						fir = sec = 0;
    
 						flag = false;
    
 					}
    
 					else
    
 					{
    
 						last = last*fir%mod;
    
 						fir = 0;
    
 						flag = false;
    
 					}	
    
 				}
    
 			}
    
 		}
    
 		if(flag)last = last*(mul(fir,sec)%mod)%mod;
    
 		else last = last*fir%mod;
    
 		printf("%lld\n",last);	
    
 	}
    
 	return 0;
    
 }

一种神奇的方法

复制代码
 #include <cstdio>

    
 #include <string>
    
 #include <cstring>
    
 #include <cstdlib>
    
 #include <iostream>
    
 #define ll long long
    
 using namespace std;
    
  
    
 char s[10010];
    
 ll m;
    
  
    
 ll mul(ll a,ll b) {
    
 	ll ret=0;
    
 	while(b) {
    
 		if(b&1) ret=(ret+a)%m;
    
 		a=(a<<1)%m; b>>=1;
    
 	}return ret;
    
 }
    
  
    
 ll Pow(ll a,ll b) {
    
 	ll ret=1;
    
 	while(b) {
    
 		if(b&1) ret=mul(ret,a);
    
 		a=mul(a,a); b>>=1;
    
 	}return ret;
    
 }
    
  
    
 ll Pow(string b, string e) {
    
 	ll t=0;
    
 	for(int i=0;i<b.length();++i) t=mul(t,10)+b[i]-'0';
    
 	ll ret=1%m;
    
 	for(int i=e.length()-1;~i;--i) {
    
 		ret=mul(ret,Pow(t,e[i]-'0'));
    
 		t=Pow(t,10);
    
 	}return ret;
    
 }
    
  
    
 void Work() {
    
 	scanf("%lld%s",&m,s);
    
 	ll ans=1%m; char *p=s,*r,*q;
    
 	while(true) {
    
 		for(q=p;isdigit(*q);++q);
    
 		for(r=q+2;isdigit(*r);++r);
    
 		ans=mul(ans,Pow(string(p,q),string(q+2,r)));
    
 		if(*r=='\0') break;
    
 		p=r+1;
    
 	} printf("%lld\n",ans);
    
 }
    
  
    
 int main() {
    
 	int T; scanf("%d",&T);
    
 	while(T--) Work();
    
 	return 0;
    
 }
复制代码
 2

    
 3
    
 4
    
 5
    
 6
    
 7
    
 8
    
 9
    
 10
    
 11
    
 12
    
 13
    
 14
    
 15
    
 16
    
 17
    
 18
    
 19
    
 20
    
 21
    
 22
    
 23
    
 24
    
 25
    
 26
    
 27
    
 28
    
 29
    
 30
    
 31
    
 32
    
 33
    
 34
    
 35
    
 36
    
 37
    
 38
    
 39
    
 40
    
 41
    
 42
    
 43
    
 44
    
 45
    
 46
    
 47
    
 48
    
 49
    
 50
    
 51
    
 52
    
 53
    
 54
    
 55
    
 56
    
 57
    
 58
    
 59
    
 60
    
 61
    
 62
    
 63
    
 64
    
 65
    
 66
    
 67
    
 68
    
 69
    
 70
    
 71
    
 72
    
 73
    
 74
    
 75
    
 76
    
 77
    
 78
    
 79
    
 80
    
 	
    
 #include<iostream>
    
 #include<cstring>
    
 #include<cstdio>
    
 #include<cstdlib>
    
 #include<cmath>
    
 #include<algorithm>
    
 #include<vector>
    
 #include<set>
    
 #include<map>
    
 #define ll long long 
    
 #define inf 1000000000
    
 using namespace std;
    
 ll read()
    
 {
    
     ll x=0,f=1;char ch=getchar();
    
     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    
     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    
     return x*f;
    
 }
    
 int T;
    
 ll M;
    
 char ch[10005];
    
 ll mul(ll a,ll b)
    
 {
    
 	ll ans=0;a%=M;
    
 	for(ll i=b;i;i>>=1,a=(a+a)%M)
    
 		if(i&1)ans=(ans+a)%M;
    
 	return ans%M;
    
 }
    
 ll qpow(ll a,ll b)
    
 {
    
 	ll ans=1;a%=M;
    
 	for(ll i=b;i;i>>=1,a=mul(a,a))
    
 		if(i&1)ans=mul(ans,a);
    
 	return ans%M;
    
 }
    
 ll pow(int a,int b,int c,int d)
    
 {
    
 	ll tmp=0,ans=1;
    
 	for(int i=a;i<=b;i++)
    
 		tmp=(mul(tmp,10)+ch[i]-'0')%M;
    
 	for(int i=c;i<=d;i++)
    
 	{
    
 		ans=mul(qpow(ans,10),qpow(tmp,ch[i]-'0'));
    
 	}
    
 	return ans;
    
 }
    
 ll solve(ll l,ll r,ll num)
    
 {
    
 	for(int i=r;i>=l;i--)
    
 		if(ch[i]=='*')
    
 		{
    
 			if(ch[i-1]!='*')return mul(solve(l,i-1,1),solve(i+1,r,num));
    
 			else 
    
 			{
    
 				int j=i-2;
    
 				while(ch[j]!='*'&&j)j--;
    
 				ll res=pow(j+1,i-2,i+1,r);
    
 				if(j==0)return res;
    
 				if(ch[j-1]=='*')return solve(l,j-2,res);
    
 				else return mul(solve(l,j-1,1),res);
    
 			}
    
 		}
    
 	ll tmp=0;
    
 	for(int i=l;i<=r;i++)tmp=(mul(tmp,10)+ch[i]-'0')%M;
    
 	if(num==1)return tmp;
    
 	else return qpow(tmp,num);
    
 }
    
 int main()
    
 {
    
 	T=read();
    
 	while(T--)
    
 	{
    
 		M=read();
    
 		scanf("%s",ch+1);
    
 		int l=strlen(ch+1);
    
 		printf("%lld\n",solve(1,l,1));
    
 	}
    
 	return 0;
    
 }

全部评论 (0)

还没有任何评论哟~