E简单瞎搞题(bitset)

简单瞎搞题

https://ac.nowcoder.com/acm/problem/17193

这个题目还有点意思。。。一开始愣是没看懂。。。暴力的做法O(100^100)超时,因为最终要是求得所有不同数的个数,我们考虑用二进制表示这个数能出现或者不能出现。二进制操作有一个非常好用的工具是bitset。如果不会bitset,http://www.cplusplus.com/reference/bitset/bitset/。因为数字最大无非是,,所以bitset开到1e6就行了,bitset从右边往左边走,它的位置表示十进制位置。感觉说不太清,直接举例子吧。
如果输入
2
1 2
1 2
先考虑,我们有,
看一下二进制是如何操作的。
图片说明
给定表示二进制串向左移动个位置,这个位置刚好就是i所对应的十进制数,一开始设,表示答案串最后一位为1没有实际意义就是为了后面的操作。然后,这个时候字符串下标1的位置字符串0变1(|有1则1),然后,这个时候字符串4的位置0变1,看到这里应该明白了,01二进制串第表示这个数不会出现,为表示这个数出现,并且下标就是对应这个数的值。我们再来考虑,看它是怎么累加的。结束后我们要保存这个结果串,然后继续遍历,这个时候,s1已经是上一个区间数的串了,在这个基础上继续左移,,当
图片说明
注意到,表示的就是(对应下标看)。然后还有,就是最后一个串,因为我们只要求出现一次的数,出现多次的会被运算覆盖掉,然后不断迭代,最后答案串的的个数就是的种类数。
代码:

#include<iostream>
#include<bitset> 
using namespace std;

const int maxn = 1100000 ;
void solved(){
    int n;cin>>n;
    bitset<maxn>s1,s2;
    s1.set(0);
    while(n--){
        s2.reset(); 
        int l,r;cin>>l>>r;
        for(int i = l ; i <= r; i++){
            s2 |= s1 << (i * i);
        }
        s1 = s2;
    }
    cout<<(int)s1.count()<<endl;
}
int main(){
    solved();
    return 0;
}
全部评论
大佬您的字串貌似是反的,起点应该是右边吧,不然左移不就越界了吗?
点赞 回复 分享
发布于 2021-06-30 21:28

相关推荐

AC鸽想进大厂:你是我见过最美的牛客女孩
点赞 评论 收藏
分享
09-01 11:31
门头沟学院 Java
buul:七牛云的吧,感觉想法是好的,但是大家没那么多时间弄他这个啊。。。不知道的还以为他是顶尖大厂呢还搞比赛抢hc,只能说应试者的痛苦考察方是无法理解的,他们只会想一出是一出
点赞 评论 收藏
分享
评论
5
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务