列表

详情


NC200204. dh的帽子

描述

 最近迷上了编程,所以慈姐给她出了一个问题给定正整数  和  ,求有多少组  满足以下条件:

                    

                     

但是  才刚刚接触编程,所以她打算求助聪明的你,如果你能帮助她,她会把她喜欢的帽子送给你。

输入描述

第一行两个整数 ,表示  的范围。

输出描述

在一行中输出一个整数 ,表示有  组  满足上述两个条件。

示例1

输入:

1 10

输出:

184

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2022-08-06 03:23:17

#include <iostream>
#include <cstring>

using namespace std;

using i64 = long long;

const int N = 20;

i64 f[N][2][2][2][2][2][2];
int numl[N], numr[N];
int lenl, lenr;
int l, r;

i64 dfs(int pos, int l1, int r1, int l2, int r2, int l3, int r3) {
    if (!pos) return 1;
    i64& v = f[pos][l1][r1][l2][r2][l3][r3];
    if (~v) return v;
    int d1 = l1 ? numl[pos] : 0, d2 = l2 ? numl[pos] : 0, d3 = l3 ? numl[pos] : 0;
    int u1 = r1 ? numr[pos] : 1, u2 = r2 ? numr[pos] : 1, u3 = r3 ? numr[pos] : 1;
    i64 res = 0;
    for (int i = d1; i <= u1; i++)
        for (int j = d2; j <= u2; j++)
            for (int k = d3; k <= u3; k++)
                if ((i ^ j ^ k) == (i | j | k)) 
                    res += dfs(pos - 1, l1 & i == d1, r1 & i == u1, l2 & j == d2, r2 & j == u2, l3 & k == d3, r3 & k == u3);
    return v = res;
}

signed main() {
    cin >> l >> r;
    memset(f, -1, sizeof f);
    while (l) numl[++lenl] = (l & 1), l >>= 1;
    while (r) numr[++lenr] = (r & 1), r >>= 1;
    cout << dfs(lenr, 1, 1, 1, 1, 1, 1);
    return 0;
}

C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 412K, 提交时间: 2019-12-21 23:07:22

#include<bits/stdc++.h>
using namespace  std;

#define ll long long 
int numl[100],numr[100];
ll dp[20][2][2][2][2][2][2];
ll dfs(int len,bool sa,bool sb,bool sc,bool ta,bool tb,bool tc )
{
	if(len==0) return 1;
	if(dp[len][sa][sb][sc][ta][tb][tc]!=-1) return dp[len][sa][sb][sc][ta][tb][tc];
	ll ans=0;
	int al=sa?numl[len]:0,ar=ta?numr[len]:1;
	int bl=sb?numl[len]:0,br=tb?numr[len]:1;
	int cl=sc?numl[len]:0,cr=tc?numr[len]:1;
	for(int i=al;i<=ar;i++)
	{
		for(int j=bl;j<=br;j++)
		{
			for(int k=cl;k<=cr;k++)
			{
				if((i^j^k)==(i|j|k))
				 ans+=dfs(len-1,sa&&i==al,sb&&j==bl,sc&&k==cl,ta&&i==ar,tb&&j==br,tc&&k==cr);
			}
		}
	}
	dp[len][sa][sb][sc][ta][tb][tc]=ans;
	return ans;
}
ll solve(int l,int r)
{
	int p1=0;
	while(l)
	{
		numl[++p1]=l%2;
		l/=2;
	}
	int p2=0;
	while(r)
	{
		numr[++p2]=r%2;
		r/=2;
	}
	return dfs(max(p1,p2),1,1,1,1,1,1);
}
int main()
{
	int l,r;
	cin>>l>>r;
	memset(dp,-1,sizeof dp);
	cout<<solve(l,r)<<endl;
	return 0;
}

C++(clang++11) 解法, 执行用时: 5ms, 内存消耗: 476K, 提交时间: 2021-02-27 18:08:54

#include<bits/stdc++.h>
using namespace std;

bool num1[20],num2[20];
long long DP[20][2][2][2][2][2][2];
long long DFS(int L,bool a,bool b,bool c,bool x,bool y,bool z)
{
	if(!L)return 1;
	if(DP[L][a][b][c][x][y][z]!=-1)return DP[L][a][b][c][x][y][z];
	long long ans=0;
	int i,j,k,al,ar,bl,br,cl,cr;
	al=(a?num1[L]:0),ar=(x?num2[L]:1);
	bl=(b?num1[L]:0),br=(y?num2[L]:1);
	cl=(c?num1[L]:0),cr=(z?num2[L]:1);
	for(i=al;i<=ar;i++)
	    for(j=bl;j<=br;j++)
	        for(k=cl;k<=cr;k++)
	            if((i^j^k)==(i|j|k))
				    ans+=DFS(L-1,a&&i==al,b&&j==bl,c&&k==cl,x&&i==ar,y&&j==br,z&&k==cr);
	return DP[L][a][b][c][x][y][z]=ans;
}
int main()
{
    int l,r,a=0,b=0;
    scanf("%d%d",&l,&r);
    memset(DP,-1,sizeof(DP));
    for(;l;l>>=1)num1[++a]=l%2;
    for(;r;r>>=1)num2[++b]=r%2;
    printf("%lld\n",DFS(max(a,b),1,1,1,1,1,1));
}

上一题