#include<bits/stdc++.h>usingnamespace std;char s[50][50];intmain(){int x, n;scanf("%d",&x);if(!x) x =1e9+7;for(int i =0; i <=40; i++)if((1<<i)>x){ n=i;break;}printf("%d %d\n", n, n+1);for(int i =0; i < n; i++)for(int j =0; j < n; j++)
s[i][j]='B';for(int i =0; i < n; i++) s[i][n]='D';for(int i =1; i < n-1; i++)for(int j =0; j < n-(i+1); j++)
s[i][j]='D';for(int i =0; i < n; i++)if((x>>i)&1) s[i][n-1]='B';else s[i][n-1]='D';for(int i =0; i < n; i++)printf("%s\n", s[i]);return0;}
C 签到
D 签到
E 数位dp或者找规律
题意:给定t组
[
l
1
,
r
1
]
,
[
l
2
,
r
2
]
[l_1, r_1] , [l_2, r_2]
[l1,r1],[l2,r2],各从中任选一个数a和b,求a^b的期望值
思路:等概率,需要求出任意两个数异或值之和。按位考虑对答案的贡献,所以需要求出
[
l
1
,
r
1
]
[l_1,r_1]
[l1,r1]和
[
l
2
,
r
2
]
[l_2,r_2]
[l2,r2]区间第p位上为1的数的个数,分别记为p1(q1=
r
1
−
l
1
+
1
−
p
1
r_1-l_1+1-p1
r1−l1+1−p1)和p2(同理q2),那么p这位的贡献就为
(
p
1
q
2
+
q
1
p
2
)
∗
2
p
(p1q2+q1p2)*2^p
(p1q2+q1p2)∗2p。可以用数位dp或者找规律来求。
ac代码:
//找规律#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;constint maxn =70;const ll mod =1e9+7;int t;
ll l1, r1, l2, r2;
ll qpow(ll a, ll b){
ll ans =1;while(b){if(b&1) ans =(ans%mod*(a%mod))%mod;
a =(a%mod*(a%mod))%mod;
b >>=1;}return ans%mod;}
ll solve(ll x, ll y)//1<<p{
ll ans =0;if(x&y){
ans = x%y+1;
x -=(y+x%y);}else x -= x%y;
ans += x/(y*2)*y;return ans;}intmain(){//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);scanf("%d",&t);while(t--){scanf("%lld %lld %lld %lld",&l1,&r1,&l2,&r2);
ll di =(r2-l2+1)%mod *((r1-l1+1)%mod)%mod;
ll sum =0;for(int i =0;(1ll<<i)<=max(r2, r1); i++){
ll cnt11 =solve(r1,1ll<<i)-solve(l1-1,1ll<<i);
ll cnt21 =solve(r2,1ll<<i)-solve(l2-1,1ll<<i);
ll cnt10 = r1-l1+1-cnt11, cnt20 = r2-l2+1-cnt21;
ll cnt =(cnt11%mod*(cnt20%mod)%mod + cnt10%mod*(cnt21%mod)%mod)%mod;
sum =(sum%mod + cnt%mod*((1ll<<i)%mod)%mod)%mod;}
ll ans =(sum%mod*((qpow(di, mod-2))%mod))%mod;printf("%lld\n", ans);}return0;}/*
p43210
00000 0
00001 1
00010 2
00011 3
00100 4
00101 5
00110 6
00111 7
01000 8
01001 9
01010 10
01011 11
01100 12
01101 13
01110 14
01111 15
10000 16
10001 17
10010 18
10011 19
10100 20
10101 21
*///数位dp#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;constint maxn =70;const ll mod =1e9+7;int t;
ll l1, r1, l2, r2;
ll a[maxn], dp[maxn][3];
ll qpow(ll a, ll b){
ll ans =1;while(b){if(b&1) ans =(ans%mod*(a%mod))%mod;
a =(a%mod*(a%mod))%mod;
b >>=1;}return ans%mod;}//统计多少个在该位上为1的
ll dfs(ll x,int pos,int p,bool limit){if(pos==0)return0;if(!limit && dp[pos][limit]!=-1)return dp[pos][limit];int up = limit?a[pos]:1;
ll sum =0;for(int i =0; i <= up; i++){if(pos==p && i==1) sum += limit ?(x%(1ll<<(p-1))+1):(1ll<<(p-1));elseif(pos>p)sum +=dfs(x, pos-1, p, limit&&i==a[pos]);}if(!limit) dp[pos][limit]= sum;return sum;}
ll cal(ll x,int p){if((1ll<<(p-1))>x)return0;int pos =0;
ll xx = x;while(x) a[++pos]=x%2, x/=2;memset(dp,-1,sizeof dp);returndfs(xx, pos, p,true);}/*
* 统计多少个在该位上有多少个不为0的
ll dfs(int pos, int p, bool limit)
{
if(pos==0) return 1;
if(!limit && dp[pos][limit]!=-1) return dp[pos][limit];
int up = limit?a[pos]:1;
ll sum = 0;
for(int i = 0; i <= up; i++)
{
if(pos==p && i==0) continue;
sum += dfs(pos-1, p, limit&&i==a[pos]);
}
if(!limit) dp[pos][limit] = sum;
return sum;
}
ll cal(ll x, int p)
{
if((1ll<<(p-1))>x) return 0;
int pos = 0;
ll xx = x;
while(x) a[++pos]=x%2, x/=2;
memset(dp, -1, sizeof dp);
return dfs( pos, p, true);
}
*/intmain(){//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);scanf("%d",&t);while(t--){scanf("%lld %lld %lld %lld",&l1,&r1,&l2,&r2);
ll di =((r2-l2+1)%mod *((r1-l1+1)%mod))%mod;
ll sum =0;for(int i =1; i <=64; i++){
ll cnt11 =cal(r1, i)-cal(l1-1, i), cnt21 =cal(r2, i)-cal(l2-1, i);
ll cnt10 = r1-l1+1-cnt11, cnt20 = r2-l2+1-cnt21;
ll cnt =((cnt11%mod*(cnt20%mod))%mod +(cnt10%mod*(cnt21%mod))%mod)%mod;
sum =(sum%mod +(cnt%mod*((1ll<<(i-1))%mod))%mod)%mod;}
ll ans =(sum%mod*((qpow(di, mod-2))%mod))%mod;printf("%lld\n", ans);}return0;}
A 签到题意: 迷宫遇到D只能向下,遇到R只能向右,遇到B既可以向下也可以向右,问从左上走到右下有多少种方案。思路:dp或者记忆化dfsB 构造题意:A的逆过程,即知道方案数,构造这样一个迷宫思路:若以方案数为20为例根据上面的构造过程可以从二进制考虑,先将1,2,4,8,16等构造出来,最后一列填D还是B取决于该位上是0还是1,是1则填B,否则填D。所以1e9+7以内的数...