放个高精度模板(加减乘除gcd)(字符串传参)(noip2020排水系统)

#include<iostream>
#include<cstdio>
#include<string>
#define R register
using namespace std;
const int N=200005;
int b[1000005],n,m,sum,map[N],last[N],d[N],l[N];
string fz[N],fm[N];
void ad(int x,int y)
{
	map[++sum]=y;last[sum]=l[x];l[x]=sum;
}
string jia(string a3,string b3)
{
	string a2,b2;
	int a[105]={},b[105]={},c[105]={};
	if (a3.size()>b3.size()) a2=b3,b2=a3;
	else a2=a3,b2=b3;
	int len=a2.size();
	for (R int i=1;i<=a2.size();i++) a[i]=a2[i-1]-'0';
	for (R int i=1;i<=b2.size();i++) b[i]=b2[i-1]-'0';
	for (R int i=1;i<=len;i++)
	{
		c[i]+=a[i]+b[i];
		c[i+1]+=c[i]/10;
		c[i]%=10;
	}
	for (R int i=len+1;i<=b2.size();++i)
	{
		c[i]+=b[i];
		c[i+1]+=c[i]/10;
		c[i]%=10;
	}
	len=b2.size();
	if (c[len+1]!=0) ++len;
	string s2="";
	for (int i=1;i<=len;++i) s2+=(c[i]+48);
	return s2;
}
string cheng(string a3,string b3)
{
	string a2,b2;
	int a[105]={},b[105]={},c[105]={};
	if (a3.size()>b3.size()) a2=b3,b2=a3;
	else a2=a3,b2=b3;
	int len;
	for (R int i=0;i<=a2.size()-1;i++) a[i+1]=a2[i]-'0';
	for (R int i=0;i<=b2.size()-1;i++) b[i+1]=b2[i]-'0';
	for (R int i=1;i<=a2.size();++i)
		for (R int j=1;j<=b2.size();++j)
		{
			c[i+j-1]+=a[i]*b[j];
			c[i+j]+=c[i+j-1]/10;
			c[i+j-1]%=10;
		}
	if (c[a2.size()+b2.size()]!=0) len=a2.size()+b2.size();
	else len=a2.size()+b2.size()-1;
	while (c[len]==0&&len>1) --len;
	string s2="";
	for (int i=1;i<=len;++i) s2+=(c[i]+48);
	return s2;
}
string cx(string s1,int sz)
{
	if (sz==0){return "0";}
	string s3="";
	while (sz>0) s3+=(sz%10+48),sz/=10;
	return cheng(s1,s3);
}
bool xy(string s1,string s2)
{
	if (s1.size()<s2.size()) return true;
	if (s1.size()>s2.size()) return false;
	for (R int i=s1.size();i>=1;i--)
	{
		if (s1[i-1]<s2[i-1]) return true;
		if (s1[i-1]>s2[i-1]) return false;
	}
	return true;
}
string jian(string s1,string s2)
{
	int a[105]={},b[105]={},c[105]={};
	for (R int i=0;i<=s1.size()-1;i++) a[i]=s1[i]-'0';
	for (R int i=0;i<=s2.size()-1;i++) b[i]=s2[i]-'0';
	for (R int i=0;i<=s1.size()-1;i++)
	{
		c[i]=c[i]+a[i]-b[i];
		if (c[i]<0) c[i]+=10,c[i+1]-=1;
	}
	int len=s1.size()-1;string s3="";
	while (c[len]==0&&len) --len;
	for (R int i=0;i<=len;++i) s3+=(c[i]+48);
	return s3;
}
string copy(string s1,int sz,int sz2)
{
	string s2="";
	for (R int i=sz;i<=sz2;++i) s2+=s1[i];
	return s2;
}
string chu(string s1,string s2)
{
	string ans="";
	int lent;
	lent=s1.size()-s2.size();
	int head=s1.size()-1;
	for (R int i=lent;i>=0;--i)
	{
		char ch='0';
		string s3=copy(s1,i,head);
		while (xy(s2,s3))
		{
			ch=ch+1;
			s3=jian(s3,s2);
		}
		ans=ch+ans;
		s1=copy(s1,0,i-1); if (s3!="0") s1+=s3;
		head=s1.size()-1;
	} 
	if (ans[ans.size()-1]=='0') ans=copy(ans,0,ans.size()-2);
	return ans;
}
string gcd(string s1,string s2)
{
	if (xy(s1,s2)) {string s3=s1;s1=s2;s2=s3;}
	string r=jian(s1,cheng(s2,chu(s1,s2)));//cout<<s1<<' '<<s2<<' '<<chu(s1,s2)<<' '<<endl;
	while (r!="0")
	{
		s1=s2;
		s2=r;
		r=jian(s1,cheng(s2,chu(s1,s2)));
	}
	return s2;
}
void bfs(int x)
{
	int tail=1,head=0;
	b[1]=x;
	fz[x]=jia(fz[x],fm[x]);
	while (head<=tail)
	{
		++head;
		if (fz[b[head]]=="0") continue;
		if (d[b[head]]==0) continue;
		fm[b[head]]=cx(fm[b[head]],d[b[head]]);
		for (R int i=l[b[head]];i!=0;i=last[i])
		{
			fz[map[i]]=jia(cheng(fz[b[head]],fm[map[i]]),cheng(fz[map[i]],fm[b[head]]));
			fm[map[i]]=cheng(fm[map[i]],fm[b[head]]);//cout<<head<<' '<<b[head]<<' '<<fz[map[i]]<<' '<<fm[map[i]]<<endl;
			string fgcd=gcd(fz[map[i]],fm[map[i]]);
			fz[map[i]]=chu(fz[map[i]],fgcd);fm[map[i]]=chu(fm[map[i]],fgcd);//cout<<fz[map[i]]<<' '<<fm[map[i]]<<endl;
			++tail;
			b[tail]=map[i];
		}
		fz[b[head]]="0",fm[b[head]]="1";
	}
}
int main()
{
	freopen("water.in","r",stdin); freopen("water.out","w",stdout);
	cin>>n>>m;
	for (R int i=1;i<=n;++i)
	{
		cin>>d[i];
		fm[i]="1";fz[i]="0";
		for (R int j=1;j<=d[i];j++)
		{
			int y;
			scanf("%d",&y);
			ad(i,y);
		}
	}
	for (R int i=1;i<=m;++i) bfs(i);
	for (R int i=1;i<=n;++i)
	{
		if (d[i]==0)
		{
			if (fz[i]=="0") {cout<<fz[i]<<' '<<fm[i]<<endl;continue;}
			string fgcd=gcd(fz[i],fm[i]);
			fz[i]=chu(fz[i],fgcd);fm[i]=chu(fm[i],fgcd);
			for (int j=fz[i].size();j>=1;j--) cout<<fz[i][j-1]; cout<<' ';
			for (int j=fm[i].size();j>=1;j--) cout<<fm[i][j-1]; cout<<endl;
		}
	}
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值