CodeForces-768B Code for 1 二分搜索线段

本文介绍了一种利用递归深度优先搜索(DFS)高效解决特定数拆分问题的方法,通过避免完整序列重建,简化了计算过程并显著提高了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题:Code for 1

题意:给定一个数N,对大于1的数在原来的位置拆分为N/2,N%2,N/2三个数。对拆分出的大于1的数同样进行拆分,直至所有的数均为0或1。对拆分后的0/1序列,询问L到R区间中1的数量。

看到这题,我直接想都没想就直接模拟了,(可能比赛的时候脑子属于装饰品)结果理所当然ML了。

后来才知道其实不需要还原最后的串就可以解答,直接用dfs做就可以了,先到了这题真的很水,代码很短。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#include<functional>
#define D long long
#define F double
#define MAX 0x7fffffff
#define MIN -0x7fffffff
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back  
#define mk make_pair  
#define fi first  
#define se second  
#define pill pair<int, int>  
using namespace std; 
#define N 100100 
#define MOD ((int)1e9+7)

D dfs(D n,D L,D R,D l,D r){
    if(L>r||R<l)return 0;
    if(n==0)return 0;
    if(n==1)return 1;
    return dfs(n/2,L,R,l,(l+r>>1)-1)+dfs(n%2,L,R,(l+r>>1),(l+r>>1))+dfs(n/2,L,R,(l+r>>1)+1,r);
}


int main()
{
    D num,L,R;
    cin>>num>>L>>R;
    D len=1;D num_=num;
    while(num>1){
        len*=2;len++;num/=2;
    }
    cout<<dfs(num_,L,R,1,len)<<endl;


    return 0;
} 

首先求出最终串的长度,用长度来代替串。
然后二分区间,如果是无用(在要求的区间外),则return 0,如果是有用的,分为两种,一种是单点,可以直接得到值,一种是区域,就继续往下dfs。

可以意会一下下面的模拟过程图
这里写图片描述

这里模拟的是L到(1+len)/2 段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值