填之前的坑。。
前言
其实也没啥写的,提高组的进阶高精也就高精除高精了(若是想到其他的以后再补)。
至于高精开根这些以后省选再写(退役flag高高立起)
思路
采用二分,mid*高精小数与高精大数做
≤
\leq
≤ 的比较
时间
O
(
n
log
n
)
O(n\log n)
O(nlogn),答案int范围内
log
\log
log是30多一点,常数写好就不怕
(至少比一个一个减要好吧
还有我不会压位,之后再补(挖坑中)
代码
luoguP2005 136ms
常数按正常休闲写法写的,跑的还算快
程序中变量名和函数名都hin形象,将就看吧
(我对我的码风还是挺有信心的)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int read(){
int x=0;int pos=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return pos?x:-x;
}
struct bigint{
long long len,num[25001];
};
int comp_less(bigint a,bigint b){
if(a.len<b.len) return 1;
else if(a.len>b.len) return 0;
else{
for(int i=1;i<=a.len;i++){
if(a.num[i]<b.num[i]) return 1;
}
return 0;
}
}
int comp_less_or_equl(bigint a,bigint b){
if(a.len<b.len) return 1;
else if(a.len>b.len) return 0;
else{
for(int i=1;i<=a.len;i++){
if(a.num[i]>b.num[i]) return 0;
else if(a.num[i]<b.num[i]) return 1;
}
return 1;
}
}
char s1[25001],s2[25001];int tans[25001],top;
bigint mul(bigint a,int b){
bigint ans;
ans.len=0;
long long tmp=0;top=0;
for(int i=a.len;i>=1;i--){
tmp+=a.num[i]*b;
tans[++top]=tmp%10;
tmp/=10;
}
while(tmp){
tans[++top]=tmp%10;
tmp/=10;
}
ans.len=top;
for(int i=1;i<=top;i++){
ans.num[i]=tans[top-i+1];
}
return ans;
}
long long div(bigint a,bigint b){
long long l=1,r=2000000001,mid;
while(l<r-1){
mid=(l+r)>>1;
if(comp_less_or_equl(mul(b,mid),a)) l=mid;
else r=mid;
//printf("%lld %lld %lld\n",l,r,mid);
}
return l;
}
int main(){
scanf("%s",s1);
scanf("%s",s2);
int l1=strlen(s1),l2=strlen(s2);
bigint a1,a2;a1.len=l1,a2.len=l2;
for(int i=0;i<l1;i++){
a1.num[i+1]=s1[i]-'0';
}
for(int i=0;i<l2;i++){
a2.num[i+1]=s2[i]-'0';
}
if(comp_less(a1,a2)){
printf("0");
return 0;
}
printf("%lld",div(a1,a2));
return 0;
}