传送门:求和
解析:
考虑在1-n的位置上放第一个1,假设第i个位置放第一个1,这样的数有: n-i个(后面 n-1 位放1或放0),答案是 lowbit(i)之和,那么一个第一1在i的数对答案的一个贡献就是 i-1 那么所有的第i个数贡献就是 n-1,n个位置的所有贡献就是: n-1, 的1在第n+1位,那么贡献就是 . 答案就是: n-1 .
代码:
#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
int read(long long &x){
long long s=0,w=1;
char c=getchar();
if(c=='-') w=-1,c=getchar();
while(c<='9'&&c>='0') s=s*10+c-'0',c=getchar();
x=s*w;
}
long long qp(long long x,long long y){
long long ans=1,tmp=x;
while(y){
if(y&1) ans=(ans%mod*tmp%mod)%mod;
tmp=(tmp%mod*tmp%mod)%mod;
y/=2;
}
return ans;
}
int main(){
long long T;
read(T);
while(T--){
long long n;
read(n);
long long n1=qp(2,n-1);
long long n2=qp(2,n);
printf("%lld\n",(((n%mod)*(n1%mod))%mod+n2)%mod);
}
return 0;
}
传送门:解锁专家
题意:统计n位01串,没有连续1的可能有多少种(例如n=3,(011)不符合,(010)符合)。
解析:一位有0,1两种,两位有01,10,00两种,三位有001,010,000,100,101。可以发现三位的前三个是通过两位的所有可能的首位加0得到的,后面两个是通过在一位的第三位加1得到的。所以这是一个斐波那契,题目不允许可能位全0串,所以要再-1.
#include<bits/stdc++.h>
using namespace std;
const int mod=433494437;
long long p[110];
int main(){
long long n,ans=1;
p[0]=0;
p[1]=2;p[2]=3;
for(int i=3;i<=110;++i){
p[i]=(p[i-1]+p[i-2])%mod;
}
while(cin>>n){
cout<<(p[n]-1+mod)%mod<<endl;//当p[n]=0时如果不+mod答案会为负数,难怪Mod数不是1e9+7
}
return 0;
}