zoukankan      html  css  js  c++  java
  • [BZOJ3329] Xorequ

    题解:

    网上的方法基本是建立在发现临位不能相等的基础上的

    这个很好证。。

    但是不利用这个特征也是可以的

    x^2x=3x

    我们考虑二进制的前i位,我们会发现3x最多涉及到了前i+2位

    于是我们可以记录一下前i位的3x的i+1,i+2位的状态,以及第i位填了什么

    因为后面的位置是不影响前面的位置的,所以前面必须要匹配

    然后这个东西数位dp一下(数位dp正着做反着做其实也差不多)

    这个dp只要你头脑清醒还是比较好打的。。。。

    对于第二问这种东西很明显是找规律

    fib数列,用正解很容易证明,矩阵求一下就好

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register ll
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define ll long long
    const ll mo=1e9+7;
    ll n,v[100],f[100][4][2][2];
    struct re{
      ll a[2][2];
      re() { a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;};
    }now;
    re js(re x,re y)
    {
      re a;
      rep(i,0,1)
        rep(j,0,1)
          rep(k,0,1)
            a.a[i][k]+=x.a[i][j]*y.a[j][k],a.a[i][k]%=mo;
      return(a); 
    }
    re fsp(ll x)
    {
      if (x==1) return(now);
      re k1=fsp(x/2);
      k1=js(k1,k1);
      if (x%2) k1=js(k1,now);
      return(k1);
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      ios::sync_with_stdio(false);
      ll T;
      now.a[0][0]=1; now.a[0][1]=1;
      now.a[1][0]=1; now.a[1][1]=0;
      cin>>T;
      rep(kk,1,T)
      {
      memset(f,0,sizeof(f));
      cin>>n;
      ll l=0,tmp=n;
      while (tmp) l++,v[l]=tmp%2,tmp/=2;
      f[0][0][0][0]=1; 
      rep(i,1,l)
      {
        if (v[i]==1)
        {
          f[i][3][1][1]=f[i-1][3][1][1];
          f[i][3][1][0]=f[i-1][3][1][0];
          f[i][2][1][1]=f[i-1][2][0][1];
          f[i][2][1][0]=f[i-1][2][0][0];
          f[i][1][1][1]=f[i-1][0][0][1];
          f[i][1][1][0]=f[i-1][0][0][0];
          f[i][1][0][0]=f[i-1][3][1][0]+f[i-1][3][1][1]
                        +f[i-1][2][0][1]+f[i-1][2][0][0];
          f[i][0][0][0]=f[i-1][1][1][0]+f[i-1][1][1][1]
                        +f[i-1][0][0][0]+f[i-1][0][0][1];
        } else
        {
          f[i][3][1][1]=f[i-1][3][1][1]+f[i-1][3][1][0];
          f[i][2][1][1]=f[i-1][2][0][1]+f[i-1][2][0][0];
          f[i][1][1][1]=f[i-1][0][0][1]+f[i-1][0][0][0];
          f[i][1][0][0]=f[i-1][3][1][0]+f[i-1][2][0][0];
          f[i][1][0][1]=f[i-1][3][1][1]+f[i-1][2][0][1];
          f[i][0][0][0]=f[i-1][1][1][0]+f[i-1][0][0][0];
          f[i][0][0][1]=f[i-1][1][1][1]+f[i-1][0][0][1];
        }
      }
      cout<<f[l][1][1][0]+f[l][0][0][0]-1<<endl;
      cout<<fsp(n+1).a[0][0]<<endl;
      }
      return 0; 
    }
  • 相关阅读:
    SpringBoot到底run了什么
    Activity生命周期
    Activities and Tasks
    Android开发指南中文版(二)Application Fundamentals
    Android开发指南中文版(三)Intents and Intent Filters
    Android开发指南中文版(一)What is Android?
    Activity的启动模式
    skydrive 中 文件夹以zip格式下载,含有中文的文件将会被改名
    装了7个虚拟机
    google reader 居然要关闭了?
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9665170.html
Copyright © 2011-2022 走看看