Description
定义一种新的运算符$。
具体地,A$B(p)的值可以用如下代码来表示。
while (A) {a[cnta++]=A%10; A/=10;}
while (B) {b[cntb++]=B%10; B/=10;}
for (int i=0; i<cnta/2; i++) swap(a[cnta-i-1],a[i]);
for (int i=0; i<cntb/2; i++) swap(b[cntb-i-1],b[i]);
nowa=nowb=0;
for (int i=1; i<=p; i++)
{
ans+=a[nowa]*b[nowb];
nowa=(nowa+1)%cnta; nowb=(nowb+1)%cntb;
}
return ans;
其中ans的值就是这个表达式的值。
已知k,p,它想找出一个x,使得l<=x<=r且x$k(p)最大。
例如l=2,r=11,k=4,p=2,那么当x=9时能使x$k(p)达到最大值。
1<=l<=r<10100000,1<=k<10100000,100000<=p<=1016
Solution
这个很显然就是数位DP嘛,
把每一位的系数求出来,(这个大家自己手推一下都能搞出来,细节比较多)
再贪心一下,我的做法是先把最高位的相同的位数剃掉(ans一定),剩下的就显然的贪心了,
贪心时可以先把高位中相同的位数先计算,剩下的就简单了。
复杂度:O(n)
Code
#include <cstdio>
#include <cstdlib>
#define max(q,w) ((q)<(w)?(w):(q))
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const LL N=1e6+5;
LL n,m,m1;
LL P,ans;
int b[N],zx[N];
int L[N],R[N];
LL f[N],g[N*2];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
void swap(LL &q,LL &w){LL t=w;w=q;q=t;}
void swap(int &q,int &w){int t=w;w=q;q=t;}
int main()
{
freopen("!.in","r",stdin);
LL q,w;char ch=' ';
for(;(ch<'0')||(ch>'9');ch=getchar());
for(;ch>='0' && ch<='9';ch=getchar())L[++L[0]]=ch-48;
for(;(ch<'0')||(ch>'9');ch=getchar());
for(;ch>='0' && ch<='9';ch=getchar())R[++R[0]]=ch-48;
for(;(ch<'0')||(ch>'9');ch=getchar());
for(;ch>='0' && ch<='9';ch=getchar())b[++b[0]]=ch-48;
fo(i,1,L[0]/2)swap(L[i],L[L[0]-i+1]);
fo(i,1,R[0]/2)swap(R[i],R[R[0]-i+1]);
scanf("%lld",&P);
if(L[0]<R[0])
{
q=P/b[0];w=P%b[0];
LL t=9;
fo(i,1,b[0])ans+=(q+((LL)i<=w))*b[i]*t;
printf("%lld\n",ans);return 0;
}
n=L[0];m=b[0];
m1=gcd(m,n);w=P/(n/m1*m);
fo(I,1,m1)
{
g[I%m1]=0;
for(int i=I;i<=m;i+=m1)g[I%m1]+=b[i];
}
fo(i,1,n)f[i]=g[i%m1]*w;
w=P%(n/m1*m);
fo(I,1,m1)
{
g[0]=0;g[1]=b[I];q=zx[I]=1;
for(int i=(I-1+n)%m;i!=I-1;i=(i+n)%m)g[++q]=b[i+1],zx[i+1]=q;
fo(i,q+1,2*q)g[i]=g[i-q];
fo(i,2,2*q)g[i]+=g[i-1];
q=w/n+2;
for(LL i=I;i<=n;i+=m1)
{
while(q*n-n+i>w&&q!=0)q--;
f[i]+=g[zx[(i-1)%m+1]-1+q]-g[zx[(i-1)%m+1]-1];
}
}
fo(i,1,n/2)swap(f[i],f[n-i+1]);
LL ans1=0;
ans=0;
while(L[n]==R[n]&&n)ans+=L[n]*f[n],n--;
ans1=ans;
fo(i,1,n)
{
ans+=R[i]*f[i];
if(R[i])ans=max(ans,(R[i]-1)*f[i]+ans1);
ans1+=9*f[i];
}
printf("%lld\n",ans);
}