1 条题解
-
0
自动搬运
来自洛谷,原作者为

Leianha
万般皆下品,惟有透彻高搬运于
2025-08-24 22:00:35,当前版本为作者最后更新于2019-10-02 12:21:42,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
高精度&找规律
今天模拟赛第一题,结果被狂虐。很明显的打表找规律的题。(数位DP?不存在的)我们珂以用我们的暴力程序来观察一下。我们设f(x)为二进制数x经过一系类变换后得到的结果,就会发现f(i)是成片分布的。举个栗子:
0000--->1
0001--->0
0010--->0
0011--->0
0100--->1
0101--->1
......
我们还可以发现后面相同的f(i)的长度为(k不定),所以我们就能够在的时间复杂度内得到 f(i)为1的个数。又因为当n奇偶性不同的时候f答案也不相同,分别考虑一下就珂以啦。
gj work(gj x) { if(x<gj(4))return gj(1); gj l=gj(4) , r=Min(x,gj(7)) , res=gj(1);int opt=1; for( ; ;l=r+gj(1) , r=Min(r*gj(2)+gj(1),x) , opt^=1) { if(opt)res=res+(r-l+gj(1)); if(r==x)break; } return res; }另外因为答案特别大,所以我们需要写高精度,并且还要转化为为二进制。
void shuchu(gj x) { if(!x.len)return (void)printf("0"); gj lin=gj(1); while(lin<=x)lin=lin*gj(2); lin=lin/2; for(;;lin=lin/2) { if(lin<=x) { printf("1"); x=x-lin; } else printf("0"); if(lin==gj(1))break; } }最后献上我
丑陋的代码#include<iostream> #include<cstring> #include<cstdio> using namespace std; int T,n,Q,ans; char ch[205]; struct gj { int len; int v[1000]; gj(){len=0;memset(v,0,sizeof(v));} gj(int x) { len=0;memset(v,0,sizeof(v)); while(x) { v[++len]=x%10; x/=10; } } friend bool operator <(const gj &a,const gj &b) { if(a.len<b.len)return 1; if(a.len>b.len)return 0; for(int i=a.len;i>=1;--i) { if(a.v[i]<b.v[i])return 1; if(a.v[i]>b.v[i])return 0; } return 0; } friend bool operator ==(const gj &a,const gj &b) { if(a.len!=b.len)return 0; for(int i=a.len;i>=1;--i) { if(a.v[i]!=b.v[i])return 0; } return 1; } friend bool operator <=(const gj &a,const gj &b) { if(a<b)return 1; else if(a==b)return 1; else return 0; } friend bool operator !=(const gj &a,const gj &b) { if(a.len!=b.len)return 1; for(int i=a.len;i>=1;--i) { if(a.v[i]!=b.v[i])return 1; } return 0; } }x,y,res; gj operator +(gj a,gj b) { int len=a.len+b.len; gj c; c.len=len; for(int i=1;i<=len;++i)c.v[i]=a.v[i]+b.v[i]; for(int i=1;i<=len;++i) { if(c.v[i]>=10) { ++c.v[i+1]; c.v[i]-=10; } } while(c.len&&!c.v[c.len])c.len--; return c; } gj operator -(gj a,gj b) { int len=max(a.len,b.len); gj c; for(int i=1;i<=len;++i)c.v[i]=a.v[i]-b.v[i]; c.len=len; for(int i=1;i<=c.len;++i) { if(c.v[i]<0) { c.v[i+1]--; c.v[i]+=10; } } while(c.len&&!c.v[c.len])c.len--; return c; } gj operator *(gj a,gj b) { gj c; for(int i=1;i<=a.len;++i) for(int j=1;j<=b.len;++j) c.v[i+j-1]+=a.v[i]*b.v[j]; c.len=a.len+b.len; for(int i=1;i<=c.len-1;++i) { if(c.v[i]>=10) { c.v[i+1]+=c.v[i]/10; c.v[i]%=10; } } while(c.v[c.len]==0&&c.len>1)--c.len; return c; } gj operator /(gj a,long long b) { gj c;int d=0; for(int i=a.len;i>=1;--i) c.v[++c.len]=((d*10+a.v[i])/b),d=(d*10+a.v[i])%b; for(int i=1;i<=c.len/2;++i)swap(c.v[i],c.v[c.len-i+1]); while(c.v[c.len]==0&&c.len>1)--c.len; return c; } ostream& operator << (ostream &out,const gj &a) { if(!a.len) { cout<<"0"; return out; } for(int i=a.len;i>=1;i--)printf("%d",a.v[i]); return out; } gj Min(gj a,gj b) { if(a<b)return a; else return b; } gj work(gj x) { if(x<gj(4))return gj(1); gj l=gj(4) , r=Min(x,gj(7)) , res=gj(1);int opt=1; for( ; ;l=r+gj(1) , r=Min(r*gj(2)+gj(1),x) , opt^=1) { if(opt)res=res+(r-l+gj(1)); if(r==x)break; } return res; } void shuchu(gj x) { if(!x.len)return (void)printf("0"); gj lin=gj(1); while(lin<=x)lin=lin*gj(2); lin=lin/2; for(;;lin=lin/2) { if(lin<=x) { printf("1"); x=x-lin; } else printf("0"); if(lin==gj(1))break; } } void slove2() { x=y=res=gj(0); scanf("%s",ch+1); for(int i=1;i<=n;++i) { x=x*2+gj(ch[i]-'0'); } scanf("%s",ch+1); for(int i=1;i<=n;++i) { y=y*2+gj(ch[i]-'0'); } res=work(y)-work(x-gj(1)); if((n&1)==(Q&1))res=y-x+1-res; shuchu(res);puts(""); } int main() { cin>>T; while(T--) { scanf("%d%d",&n,&Q); slove2(); } fclose(stdin);fclose(stdout); return 0; }
- 1
信息
- ID
- 3448
- 时间
- 1000ms
- 内存
- 250MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者