求一个字符串有多少个子串的十进制是三的倍数
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;
}