2023牛客暑期多校训练营7(C/I/M)

目录

C.Beautiful Sequence

I.We Love Strings 

M.Writing Books


C.Beautiful Sequence

思路:显然若得到了a[1],则整个序列a我们都知道了。所以我们要求出第k大的a[1],这个可以利用序列a为不递减序列的性质来得出。

首先,由题意可得:

a[2]=a[1]^b[1]

a[3]=a[2]^b[2]=(a[1]^b[1])^b[2]

a[4]=a[3]^b[3]=((a[1]^b[1])^b[2])^b[3]

......

得出a[i]=a[1]^(序列b的前缀i异或和)

我们把序列b的前缀i异或和定义为f[i],因为序列a不递减,所以:

a[i]<=a[i+1]

=>   a[1]^f[i-1] <= a[1]^f[i]

首先我们先初始化a[1]二进制位为-1,这代表a[1]的这个位可以是0,也可以是1。然后我们再根据a[1]^f[i-1] <= a[1]^f[i] 这个公式来得出a[1]的哪些位它是确定的,不能是-1。

我们需要从高位往低位贪心,因为如果a[1]^f[i-1]的一个高位如果是1,而a[1]^f[i]的这个位是0,那么低位再怎么变,a[1]^f[i-1]也必然小于a[1]^f[i]。比如两个二进制数1????和0????,就算左边的低位全是1,右边的高位全是0,也就是变成10000和01111,左边依然大于右边。

然后我们从高位到低位怎么贪心呢?找f[i]的f[i-1]的从高位到低位,第一个不同的位即可,我们设这个是第k位。此时a[1]的第k位必须和f[i]第k位的值相同,这样子就能让f[i]^a[1]的第k位是0,f[i+1]^a[1]第k位是1,保证了前者小于后者。在此之前a[i]的第k位必须等于-1或者等于f[i]的第k位,否则输出-1。

此时我们得到了n个-1的值,我们我们最多能表示第2的n次方大的值,此时我们只需将(k-1)拆分成二进制依次填入-1的位置即可。具体实现见代码。

代码:

void solve() {a[1]=0;mem(now,-1);int n,k;cin>>n>>k;for(int i=1; i<n; i++) {cin>>b[i];f[i]=(f[i-1]^b[i]);}for(int i=0; i<n-1; i++) {for(int j=29; j>=0; j--) {if((f[i]>>j&1ll)!=(f[i+1]>>j&1ll)) {//找到高位第一个不相等的二进制位if(now[j]==-1)now[j]=(f[i]>>j&1ll);else if(now[j]==(f[i+1]>>j&1ll)) {//如果该位已经确定,并且与想要填的数相反,则输出-1cout<<-1<<endl;return;}break;//高位比上一个大了之后,就不用再管低位了}}}k--;//去掉初始不变的情况,方便替换-1int maxx=0;for(int i=0; i<30; i++) {if(now[i]==-1)maxx=maxx*2+1;}if(maxx<k) {cout<<-1<<endl;return;}vector<int>v;while(k) {//将k转换为二进制填入v.push_back({k%2});k/=2;}reverse(v.begin(),v.end());for(int i=0; i<30; i++) {if(!v.size())break;//填完了就退出if(now[i]==-1) {//依次填入now[i]=v.back(),v.pop_back();}}for(int i=0; i<30; i++)now[i]=max(now[i],0ll);//把没填的-1变成0for(int i=29; i>=0; i--) a[1]=a[1]*2+now[i];;//得出a[1]的值cout<<a[1]<<" ";for(int i=2; i<=n; i++)cout<<(b[i-1]^a[i-1])<<" ",a[i]=(b[i-1]^a[i-1]);//根据a[1]得出整个序列acout<<endl;
}

I.We Love Strings 

思路:因为字符串长度不相同的字符串,两两之间肯定不能匹配,所以我们根据字符串长度大小来求解。在lenth<=20时我们暴力枚举字符串所有情况进行求解,而在lenth>20的时候我们暴力容斥来求解。

那么为什么这个临界值为20呢?

我们设临界值为N,暴力枚举所有情况的复杂度主要由字符串长度决定,复杂度为:

而容斥的复杂度主要由容斥的集合大小决定,而这个集合的最大大小又由n的最大值和N共同决定,它的复杂度为:

总的复杂度为他们两个相加。

此时N取太大或者取太小,都会使得一方的复杂度过大,此时取400的根号,也就是N=20,是最好的。

具体实现见代码。

代码:

int pp(vector<int>v,string s,int n) {for(int i=0; i<n; i++) {if(s[i]!='?'&&v[i]!=s[i]-'0')return 0;//如果两个串确定有位置不同了,则匹配失败 }return 1;//匹配成功 
}
int f1(int n) {int sum=0;for(int i=0; i<(1<<n); i++) {//枚举这个长度01串的所有可能。 vector<int>s;for(int j=0; j<n; j++) {s.push_back((i>>j&1ll));} //将枚举的串存入vector for(int i=0; i<v[n].size(); i++) {if(pp(s,v[n][i],n)) {//如果有一个串能和这个枚举的串匹配,答案+1 sum++;break;}}}return sum;
}
int f2(int n) {int m=v[n].size(),ans=0;//注意i要从1开始,若从0开始则会使答案增加 for(int i=1; i<(1ll<<m); i++) {//枚举集合内的串int sum=1;for(int j=0; j<n; j++) {//枚举串的每个位 int cnt0=0,cnt1=0;for(int k=0; k<m; k++) {//表示这是集合内第几个串 if((i>>k&1ll)) {if(v[n][k][j]=='0')cnt0++;if(v[n][k][j]=='1')cnt1++;}}if(cnt0&&cnt1) {//若该位上确定的数不一致,则不能进行容斥 sum=0;break;}if(!cnt0&&!cnt1)sum=sum*2%mod;//该位上全是?,贡献*2 }int now=__builtin_popcount(i); if(now%2)ans=(ans+sum)%mod; //进行容斥 else ans=(ans-sum+mod)%mod;}return ans;
}
void solve() {int n,ans=0;cin>>n;for(int i=1; i<=n; i++) {string s;cin>>s;v[(int)s.size()].push_back(s);//将字符串根据长度分类 }for(int i=1; i<=400; i++) {if(!v[i].size())continue;if(i<=20)ans=(ans+f1(i))%mod;//若长度<=20则暴力求解 else ans=(ans+f2(i))%mod;//否则暴力容斥 }cout<<ans<<endl;
}

M.Writing Books

思路:显然1~9对于答案的贡献为1*9,10~99对于答案的贡献为2*90,100~999对于答案的贡献为3*900......。分块求出贡献即可。

代码:

void solve() {int n,l=1,r=10,now=1,ans=0;cin>>n;while(l<=n){if(n>=r-1)ans+=(r-l)*now;else ans+=(n-l+1)*now;now++,l=r,r*=10;}cout<<ans<<endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/63288.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LVGL学习笔记 28 - 键盘keyboard

目录 1. 设置关联文本框 2. 设置模式 2.1 LV_KEYBOARD_MODE_TEXT_LOWER 2.2 LV_KEYBOARD_MODE_TEXT_UPPER 2.3 LV_KEYBOARD_MODE_SPECIAL 2.4 LV_KEYBOARD_MODE_NUMBER 2.5 LV_KEYBOARD_MODE_USER_1 ~ LV_KEYBOARD_MODE_USER_4 3. 使能弹窗模式 4. 更改按键布局 5. 事…

【el-image图片查看时 样式穿透表格问题】

element-ui el-image图片查看 样式混乱 解决方式 ::v-deep(.el-table__cell) {position: static !important; // 解决el-image 和 el-table冲突层级冲突问题 }加个样式即可

JavaScript、TypeScript、ES5、ES6之间的联系和区别

ECMAScript&#xff1a; 一个由 ECMA International 进行标准化&#xff0c;TC39 委员会进行监督的语言。通常用于指代标准本身。JavaScript&#xff1a; ECMAScript 标准的各种实现的最常用称呼。这个术语并不局限于某个特定版本的 ECMAScript 规范&#xff0c;并且可能被用于…

大数据扫盲(1): 数据仓库与ETL的关系及ETL工具推荐

在数字化时代&#xff0c;数据成为了企业决策的关键支持。然而&#xff0c;随着数据不断增长&#xff0c;有效地管理和利用这些数据变得至关重要。数据仓库和ETL工具作为数据管理和分析的核心&#xff0c;将帮助企业从庞杂的数据中提取有价值信息。 一、ETL是什么&#xff1f; …

Java的switch语句块

说明 Java的switch语句块可以用于多个分支的判断执行。每个case分支执行完后&#xff0c;要么退出方法体&#xff08;用return语句&#xff09;、要么退出switch语句块&#xff08;用break语句&#xff09;、要么继续往下执行。但如果一个case执行完后&#xff0c;要继续执行下…

在 Android 上使用机器学习套件检测人脸

须知事项 此 API 需要 Android API 级别 19 或更高级别。确保应用的 build 文件使用的 minSdkVersion 值不小于 19。 请务必在您的项目级 build.gradle 文件中的 buildscript 和 allprojects 部分添加 Google 的 Maven 代码库。 将 Android 版机器学习套件库的依赖项添加到模…

Linux平台下搭建GB28181服务器(WVP+ZLMediakit)

文章目录 什么是GB28181平台依赖项搭建步骤配置Redis和MySQL配置ZLMediakit配置WVP 使用效果封装成Docker镜像 什么是GB28181 GB28181(国标28181)&#xff0c;全称为《中华人民共和国公共安全视频监控联网系统技术要求》&#xff0c;是中国国家标准委员会发布的一个针对公共安…

springboot+mybatis+mybatis-plus对crud项目进行改进

springbootmybatis实现简单的增、删、查、改https://blog.csdn.net/heyl163_/article/details/132197201上一篇文章&#xff0c;已经详细地介绍了怎么通过springboot项目整合mybatis实现简单的数据库表的增删改查功能&#xff0c;是最简单的springboot项目的结构。所以有很多问…

易服客工作室:如何在WordPress网站中举办虚拟活动

您是否正在寻找举办和管理虚拟活动的最佳方式&#xff1f; 也许您想在线举行下一次会议或举办有关您的产品和服务的网络研讨会。您可能担心它太贵&#xff0c;或者您没有技术知识来实现​​它。 在本文中&#xff0c;我们将列出您所需的在线服务的所有设备&#xff0c;并教您…

【vue3】基础知识点-setup语法糖

学习vue3&#xff0c;都会从基础知识点学起。了解setup函数&#xff0c;ref&#xff0c;recative&#xff0c;watch、comptued、pinia等如何使用 今天说vue3组合式api&#xff0c;setup函数 在学习过程中一开始接触到的是这样的&#xff0c;定义数据且都要通过return返回 <…

Map中compute、putIfAbsent、computeIfAbsent、merge、computeIfPresent使用

目录 putIfAbsent computeIfAbsent computeIfPresent compute merge putIfAbsent 解释&#xff1a;【不存在则添加】&#xff0c;如果map中没有该key&#xff0c;则直接添加&#xff1b;如果map中已经存在该key&#xff0c;则value保持不变 default V putIfAbsent(K key,…

Linux文件属性与权限管理(可读、可写、可执行)

Linux把所有文件和设备都当作文件来管理&#xff0c;这些文件都在根目录下&#xff0c;同时Linux中的文件名区分大小写。 一、文件属性 使用ls -l命令查看文件详情&#xff1a; 1、每行代表一个文件&#xff0c;每行的第一个字符代表文件类型&#xff0c;linux文件类型包括&am…