首页 > 其他分享 >ZROI 十连测 Day4

ZROI 十连测 Day4

时间:2023-04-20 15:55:06浏览次数:29  
标签:十连测 int Day4 200010 seed mod include ZROI size

上一次写题解也是若干年前的事了。

不过今天的题确实比较好改。

命题

签到题。状压一下看是任意还是存在,从前边两个状态与或者或出来。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int n,q,dp[21][1<<20];
char s[1<<20];
int main(){
    scanf("%d%s%d",&n,s,&q);
    for(int i=0;i<(1<<n);i++)dp[0][i]=s[i]-'0';
    for(int i=1;i<=n;i++){
        for(int j=0;j<(1<<i);j++){
            for(int k=0;k<(1<<n-i);k++){
                int s=(k<<i)|j;
                if((j>>i-1)&1)dp[i][s]=dp[i-1][s]|dp[i-1][s^(1<<i-1)];
                else dp[i][s]=dp[i-1][s]&dp[i-1][s^(1<<i-1)];
            }
        }
    }
    while(q--){
        int x;scanf("%d",&x);
        putchar(dp[n][x]+'0');
    }
    puts("");
    return 0;
}

分组

赛时口胡出了 \(O(n^2)\) 的,没写。饥饿。

题解的线性做法看不懂,来个思路不太一样的。

仍然分成两种情况考虑:在 \(a_k\) 之前填满一组和在 \(a_k\) 及以后填满一组。先看第一种。假设我们在 \(a_i\) 前填满一边,那么总数显然 \(2^{a_i}\),方案呢?我们用总的减掉没填满的方案即可。递推没填满的方案时考虑元素 \(i\) 分到哪一组,再减掉它正好填满的方案。

然后是第二种,即在 \(a_k\) 及以后填满的。这样的话,前面有 \(a_k-k\) 个被分到了两组。此时我们第一组的个数显然不能超过 \(n-k\)。于是枚举第一组的个数减掉不合法的即可。通过这种方式我们成功避免了对后缀和的讨论。

别忘了最后 \(\times 2\)。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int mod=998244353;
int n,q,ans,jc[200010],inv[200010],pw[200010],invpw[200010],s[200010],a[200010];
int qpow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}
int C(int n,int m){
    if(n<m)return 0;
    return 1ll*jc[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
    scanf("%d%d",&n,&q);jc[0]=inv[0]=pw[0]=invpw[0]=s[0]=1;
    for(int i=1;i<=2*n;i++)jc[i]=1ll*jc[i-1]*i%mod,pw[i]=(pw[i-1]<<1)%mod;
    inv[2*n]=qpow(jc[2*n],mod-2);invpw[2*n]=qpow(pw[2*n],mod-2);
    for(int i=2*n-1;i>=1;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod,invpw[i]=2ll*invpw[i+1]%mod;
    for(int i=1;i<=2*n;i++)s[i]=(2ll*s[i-1]-C(i-1,n-1)+mod)%mod;
    while(q--){
        int k;scanf("%d",&k);ans=0;
        for(int i=1;i<=k;i++){
            scanf("%d",&a[i]);
            ans=(ans+1ll*invpw[a[i]]*(pw[a[i]-i]-s[a[i]-i]+mod))%mod;
        }
        int ret=s[a[k]-k];
        for(int i=n-k+1;i<n;i++)ret=(ret-C(a[k]-k,i)+mod)%mod;
        ans=(ans+1ll*ret*invpw[a[k]])%mod;
        printf("%d\n",(ans<<1)%mod);
    }
    return 0;
}

题目

简单题,不知道为啥场上根本没看。

考虑到每个相同的 \(a_i\) 一定是递减的。那么每个 \(a_i\) 可以从前面最后一个 \(a_i-1\) 转移得到,于是偏序关系形成一个 DAG。显然每个位置的答案就是 \(n+1-size_i\),其中 \(size_i\) 为比 \(i\) 大的个数。

那这个很好统计,我们先倒着扫一遍,先不考虑递减,把转移边的 \(size\) 先累加进来,然后正着扫的时候开个桶记录之前所有 \(a_i\) 的 \(size\) 之和就能解决递减的问题。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int mod=998244353;
int n,lim,seed,ans,a[10000010],pre[10000010],pos[10000010],size[10000010],cnt[10000010];
int __my_rand (int *seed) 
{
    *seed = *seed * 1103515245 + 12345;
    return ((unsigned)*seed) / 34;
}
void gen (int N, int Lim, int seed, int* a) 
{
    int cur = 0;
    for (int i = 1; i <= N; i ++) 
    {
        int rd = __my_rand(&seed);
        if (rd % std::min(10, cur + 1) == 0 && cur < Lim) a[i] = ++cur;
        else a[i] = (__my_rand(&seed) % cur) + 1;
    }
}
int main(){
    scanf("%d%d%d",&n,&lim,&seed);
    gen(n,lim,seed,a);
    for(int i=1;i<=n;i++)pre[i]=pos[a[i]-1],pos[a[i]]=i;
    for(int i=n;i>=1;i--)size[i]++,size[pre[i]]+=size[i];
    int pw=1;
    for(int i=1;i<=n;i++){
        cnt[a[i]]+=size[i];
        ans=(ans+1ll*pw*(n+1-cnt[a[i]]))%mod;
        pw=233ll*pw%mod;
    }
    printf("%d\n",ans);
    return 0;
}

标签:十连测,int,Day4,200010,seed,mod,include,ZROI,size
From: https://www.cnblogs.com/gtm1514/p/17337155.html

相关文章

  • day49 121. 买卖股票的最佳时机 |
    给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任......
  • day49(2023.4.18)
    1.MySQL事务 2.使用事务 3.事务的并发问题 4.事务的隔离级别 5.用户管理 6.使用Navicat创建用户  7.使用Navicat分配权限8.测试一下分配好的权限 9.删除用户 10.数据的导出 11.分页查询  day49(2023.4.18)......
  • scrum项目冲刺_day4会议总结
    今日团队任务:图片转excel(5天)前端开发(需团队风格统一)调用接口(后端),json数据->excel前后端连接           任烁玚(进行中)            图片转html(8天)前端开发(需团队风格统一)图片转为pdf(存储)pdf转html(调用接口)[html存储到数据库]前后台数据同......
  • day47(2023.4.16)
    1.聚合函数 2.AVG和SUM函数 3.MIN和MAX函数 4.COUNT函数 5.GROUPBY数据分组 6.在多列上使用分组 7.HAVING约束分组结果 8.聚合函数,与数据分组,小练习 day47(2023.4.16)......
  • 团队项目Scrum冲刺-day4
    这个作业属于哪个课程2023软件工程—双学位这个作业要求在哪里团队作业4——项目冲刺这个作业目标团队项目Scrum冲刺-day4目录1.会议1.1昨日已完成工作1.2今日计划完成的工作1.3工作中遇到的困难2.燃尽图3.代码/文档签入记录4.模块代码5.每日每人总结1.会议1......
  • day46(2023.4.15)
    1.多表查询 2.迪卡尔乘积 3.等值连接 4.非等值连接 5.自连接 6.99交叉连接 7.99自然连接 8.99内连接 9.外连接查询 10.多表查询,连接小练习 day46(2023.4.15)......
  • scrum项目冲刺_Day4会议总结
    今日团队任务:图片转excel(5天)前端开发(需团队风格统一)调用接口(后端),json数据->excel前后端连接           任烁玚(进行中)            图片转html(8天)前端开发(需团队风格统一)图片转为pdf(存储)pdf转html(调用接口)[html存储到数据库]前后台数据同......
  • Day4
        3.代码示例#include<iostream>usingnamespacestd;intmain(){inta1,a2,a3,a4,s,m;for(a1=0;a1<=9;a1++){for(a3=0;a3<=9;a3++){if(a1!=a3){s=a1*1000+a1*100+a3*10+a3;//cout<&l......
  • docker-day4——Dockerfile、docker私有仓库、dockercompose介绍、dockercompose部署f
    目录一、Dockerfile1.1常用和不常用命令1.2dockerfile构建一个djagno项目二、docker私有仓库2.1镜像传到官方仓库2.2镜像分层2.3私有仓库搭建三、dockercompose介绍四、dockercompose部署flask+redis项目4.1新建flask项目app.py4.2编写Dockerfile--》用于构建flask项目的......
  • day45 70. 爬楼梯 |
    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?确定dp数组以及下标的含义dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法。确定递推公式在动态规划:494.目标和 (opensnewwindow)、 动态规划:518.零钱兑换......