• Codeforces Round #631 (Div. 1) B. Dreamoon Likes Sequences 题解(思维+求贡献)


    题目链接

    题目大意

    让你构造一个严格单调上升的数组a满足\(1<=a_1<a_2<....a_n<=d\)

    而且要使得这个数组的异或前缀和也满足严格单调上升,求有多少个满足条件的数组(mod m)

    题目思路

    首先这个数组的性质很容易观察就是后一个数化为二进制的最高位1要比第上一个高

    然后我就不会了

    我还以为是枚举数组长度啥的,果然是我太菜了

    这种类型的题目需要求贡献。枚举位数为 i 的数是否在序列中出现并计算对答案的贡献,根据乘法原理相乘即答案。

    当位数小于log(d)的位数,贡献则为\(2^i+1\)(位数为i的个数或不出现)

    还要注意减去n=0的情况

    代码

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<unordered_map>
    #define fi first
    #define se second
    #define debug printf(" I am here\n");
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-10;
    int d,m;
    signed main(){
        int _;scanf("%d",&_);
        while(_--){
            scanf("%d%d",&d,&m);
            ll ans=1;
            for(int i=0;(1<<i)<=d;i++){
                ans=ans*(min((1<<i)+1,d-((1<<i)-1)+1))%m;
                //可以选(1<<i)或者不选+1
            }
            ans=(ans-1+m)%m;//数列不能为0
            printf("%lld\n",ans);
        }
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    dockerk个人学习(0)
    ubuntu编译python源码的坑
    查找大目录
    ubuntu 远程gui显示
    paramiko模块
    python open和file的区别
    python type metaclass
    python 生成器 迭代器 yiled
    博客暂停更新,请移步新主页
    win10禁用自动更新服务
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/13755419.html
Copyright © 2020-2023  润新知