数学刷题记

求一个字符串有多少个子串的十进制是三的倍数
str[]   1 1 1 1 1 1 
sum[] 0 1 2 0 1 2 0
//sum为前缀和mod(3)
//if sum[x]==sum[y],则str(x,y]一定能够是3的倍数

那么对于区间内是三的倍数的子串的个数就是
在这里插入图片描述
在这里插入图片描述如果是300的话,就是后面多两个0,那么就是找和两个0前面的前缀和的余数一样的数有几个就可以了

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=1e5+100;
int y[3];
int main()
{
    string a;
    cin>>a;

    LL ans=0;
    int pre=0;
    for(int i=0;i<a.length();i++){
        if(a[i]=='0') ans++;
        if((i+1)<a.length()&&a[i]=='0'&&a[i+1]=='0') ans++;
    }
    y[0]=1;
    for(int i=0;i<a.length();i++){
        pre=(pre+(a[i]-'0'))%3;
        cout<<pre<<endl;
        //y[pre]++;
        if((i+1)<a.length()&&a[i+1]=='0'&&a[i+2]=='0') ans+=y[pre];
        y[pre]++;
    }

    cout<<ans<<endl;
    return 0;
}

CF 100637 C 组合数+二分

【题意】给定n,m求c=c xm m+ c xm-1 m-1+……+cx1 1的xm,xm-1,x1
【题解】对于每一个x用二分查找,(其实我也没有很理解,如果有大大想要讨论的话,欢迎私聊)

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
LL n,m;
LL calc(LL x,LL y)
{
	if(x<y) return 0;
	LL ret=1;
	y=min(y,x-y);
	for(int i=1;i<=y;i++){
		ret=ret*(x-i+1)/i;
		if(ret<0) return -1;
	}
	if(ret>n) return -1;
	return ret;
}
int main()
{
	scanf("%lld%lld",&n,&m);
	while(m--){
		LL l=m,r=1e9,mid;
		while(l<r){
			mid=(l+r+1)>>1;
			if(calc(mid,m+1)<0) r=mid-1;
			else l=mid;
		}
		n=n-calc(l,m+1);
		cout<<l<<" ";
	}
	
	return 0;
 } 

CF 100637 J 阶乘构造

【题意】对于p,q p/q=a1+a2/2!+a3/3!+……+an/n!
【题解】这个式子可以这样子理解a1为该式子的整数部分,后面是该式子的小数部分,首先把整数部分减去,然后把2乘过来,整除得到的就是a2,然后分母p*2%q/q就是后面那一部分一次类推,直到p等于0

# include <bits/stdc++.h>
using namespace std;

typedef unsigned long long LL; 
int main()
{
    LL p,q,i=0;
    cin>>p>>q;
    while(p){
        i++;
        p=p*i;
        cout<<p/q<<" ";
        p=p%q;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值