bzoj3329: Xorequ 数位DP
题目链接
题解
x^3x=2x
x^2x=3x
因为
a^b+((a&b)<<1)=a+b
x^2x=x+2x
那么x和2x的二进制表示中不存在相邻的1
对于第一问数位dp
第二问写出现递推式矩乘优化一下
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(p,x,k) for(int p = x;p <= k;++ p)
#define per(p,x,k) for(int p = x;p >= k;-- p)
#define gc getchar()
#define pc putchar
#define LL long long
inline LL read() {
LL x = 0,f = 1;
char c = gc;
while(c < '0' || c > '9') c = gc;
while(c <= '9' && c >= '0') x = x * 10 + c -'0',c = gc;
return x ;
}
void print(LL x) {
if(x < 0) {
pc('-');
x = -x;
}
if(x >= 10) print(x / 10);
pc(x % 10 + '0');
}
const int maxn = 107;
const int mod = 1e9 + 7;
struct Matrix {
LL a[3][3];
Matrix() {memset(a,0,sizeof a); }
Matrix operator * (const Matrix &t) const{
Matrix ret;
rep(k,0,1)
rep(i,0,1)
rep(j,0,1) {
(ret.a[i][j] += a[i][k] * t.a[k][j] % mod) %= mod;
}
return ret;
}
} ;
int n,m;
int bit[100];
LL f[107][3];
LL dfs(int x,int lim,int las) {
if(!x) return 1;
if(!lim && f[x][las]) return f[x][las];
LL ret = 0;
int ulim = lim ? bit[x] : 1;
ret += dfs(x - 1,lim && !ulim,0);
if(ulim && !las) ret += dfs(x - 1,lim,1);
ret;
if(!lim) f[x][las] = ret;
return ret;
}
LL solve(LL n) {
int cnt = 0;
while(n) {
if(n & 1) bit[++ cnt] = 1;
else bit[++ cnt] = 0;
n >>= 1;
}
return dfs(cnt,1,0) - 1;
}
LL fstpow(Matrix a,LL k) {
Matrix ret;
ret.a[0][0] = ret.a[0][1] = 1;
for(;k;k >>= 1,a = a * a)
if(k & 1) ret = ret * a;
return ret.a[0][0] ;
}
int main() {
//freopen("1.in","r",stdin); freopen("A.out","w",stdout);
Matrix a;
a.a[0][0] = a.a[0][1] = a.a[1][0] = 1;
int T = read();
rep(i,1,T) {
LL n;
n = read();
print(solve(n));
pc('\n');
print(fstpow(a,n));
pc('\n');
}
return 0;
}