当前位置: 首页 > news >正文

2023牛客暑期多校训练营7 CI「位运算」「根号分治+容斥」

C-Beautiful Sequence_2023牛客暑期多校训练营7 (nowcoder.com)

题意:

给定一个b序列,a序列满足 a [ i − 1 ] < = a [ i ] a[i-1]<=a[i] a[i1]<=a[i] a [ i ] ⊕ a [ i + 1 ] = b [ i ] a[i]\oplus a[i+1]=b[i] a[i]a[i+1]=b[i],求字典序第k大的满足条件的a序列,若不存在则输出-1。

思路:

我们对b数组求一个前缀和可以发现:

p r e [ 1 ] = 0 ⊕ b [ 1 ] = a [ 1 ] ⊕ a [ 2 ] pre[1]=0\oplus b[1]=a[1]\oplus a[2] pre[1]=0b[1]=a[1]a[2]

p r e [ 2 ] = p r e [ 1 ] ⊕ b [ 2 ] = a [ 1 ] ⊕ a [ 2 ] ⊕ a [ 2 ] ⊕ a [ 3 ] = a [ 1 ] ⊕ a [ 3 ] pre[2]=pre[1]\oplus b[2]=a[1]\oplus a[2]\oplus a[2]\oplus a[3]=a[1]\oplus a[3] pre[2]=pre[1]b[2]=a[1]a[2]a[2]a[3]=a[1]a[3]

……

依次类推,可以发现 p r e [ i ] = a [ 1 ] ⊕ a [ i + 1 ] pre[i]=a[1]\oplus a[i+1] pre[i]=a[1]a[i+1],对于每一组 p r e [ i ] pre[i] pre[i] p r e [ i + 1 ] pre[i+1] pre[i+1],考虑二进制从最高位开始查询,当某一位不同的时候一定是因为 a [ i + 1 ] a[i+1] a[i+1]的这位为1而 a [ i ] a[i] a[i]的这位为0,于是我们可以确定 a [ 1 ] a[1] a[1]的某一位,遍历完成后会发现可能有一部分位置(sum)的值并未确定,所以所有可能的a序列就有 1 < < s u m 1<<sum 1<<sum个,而字典序第k大的就是 a [ 1 ] a[1] a[1]的取值为第k大的,确定 a [ 1 ] a[1] a[1]后即可通过b数组求得答案。

AC代码:
#include <bits/stdc++.h>
using namespace std;
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
#define int ll
#define pb push_back
#define eb emplace_back
#define m_p make_pair
const int mod = 998244353;
#define mem(a,b) memset(a,b,sizeof a)
#define pii pair<int,int>
#define fi first
#define se second
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 50;
//__builtin_ctzll(x);后导0的个数
//__builtin_popcount计算二进制中1的个数
ll a[N],b[N],pre[N];
int numa[33];void work() {int n,k;cin>>n>>k;pre[0]=0;a[1]=0;for(int i=1;i<n;++i){cin>>b[i];pre[i]=pre[i-1]^b[i];}for(int i=0;i<=30;++i)numa[i]=-1;for(int i=n-1;i>=1;--i){for(int j=30;j>=0;--j){if(((pre[i]>>j)&1)!=((pre[i-1]>>j)&1)){numa[j]=((pre[i-1]>>j)&1);break;}}}ll num=0;for(int i=0;i<30;++i){if(numa[i]==-1)num++;}if((1<<num)<k){cout<<"-1\n";return;}k--;for(int i=30;i>=0;--i){if(numa[i]==-1){if((k>>num)&1) numa[i]=1;else numa[i]=0;num--;}}ll x=1;for(int i=0;i<=30;++i){if(numa[i]==1)a[1]+=x;x*=2;}for(int i=2;i<=n;++i){a[i]=a[i-1]^b[i-1];if(a[i]<a[i-1]){cout<<"-1\n";return;}}for(int i=1;i<=n;++i){cout<<a[i]<<" \n"[i==n];}
}signed main() {io;int t=1;cin >> t;while (t--) {work();}return 0;
}

I-We Love Strings_2023牛客暑期多校训练营7 (nowcoder.com)

题意:

给定n个01?字串,其中?可以是0也可以是1,询问有多少个01字串符合至少一个给定的正则串。

思路:

根号分治

在字串长小于20( s q r t ( 400 ) sqrt(400) sqrt(400))时dfs暴力找,总复杂度不会超过 2 21 2^{21} 221

大于20时,容斥:奇加偶减

AC代码:
#include <bits/stdc++.h>
using namespace std;
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
#define int ll
#define pb push_back
#define eb emplace_back
#define m_p make_pair
const int mod = 998244353;
#define mem(a,b) memset(a,b,sizeof a)
#define pii pair<int,int>
#define fi first
#define se second
const int inf = 0x3f3f3f3f;
const ll N = 405;
//__builtin_ctzll(x);后导0的个数
//__builtin_popcount计算二进制中1的个数
ll ans=0;
vector<string>a[N];
string tmp;
int n;void small(int now,int len){if (now==len+1){for(auto x:a[len]){bool ok=1;for(int j=0;j<len;j++) {if(x[j]=='?') continue;if(x[j]!=tmp[j]){ok=0;break;}}if (ok) {ans++;break;}}return ;}tmp+='0';small(now+1,len);tmp.pop_back();tmp+='1';small(now+1,len);tmp.pop_back();
}void big(int len,int size){ll m=1<<size;//正则串随意组合的情况数for(int i=1;i<m;++i){//枚举所有可能int cnt=0,ok=1;tmp.clear();for(int j=0;j<len;++j)tmp+="?";for(int j=0;j<size;++j){//枚举每种正则串的组合方式if(i>>j&1){cnt++;for(int t=0;t<len;++t){//枚举每一位char x=a[len][j][t];if(tmp[t]=='?'){tmp[t]=x;}else if(x!='?'&&tmp[t]!=x){ok=0;break;}}if(!ok)break;}}if(!ok)continue;int p=1;for(int j=0;j<len;++j){if(tmp[j]=='?')p=p*2%mod;//计算有多少个未确定的字符,每个未确定代表两种可能}if(cnt&1){ans=(ans+p)%mod;}else ans=(ans-p)%mod;}
}void work() {cin>>n;for(int i=1;i<=n;++i){string s;cin>>s;a[s.size()].pb(s);}for(int i=1;i<N;++i){if(!a[i].size()){continue;}if(i<=20){tmp.clear();small(1,i);}else{big(i,a[i].size());}}ans%=mod;cout<<ans<<'\n';
}signed main() {io;int t=1;//cin >> t;while (t--) {work();}return 0;
}
http://www.lryc.cn/news/154576.html

相关文章:

  • YOLOv5算法改进(10)— 替换主干网络之GhostNet
  • Android Canvas的使用
  • AI批量写文章伪原创:基于ChatGPT长文本模型,实现批量改写文章、批量回答问题(长期更新)
  • git常用场景记录 | 拉取远程分支A合并到本地分支B - 删除上一次的commit
  • 源码角度解析SpringBoot 自动配置
  • 【原创】H3C路由器OSPF测试
  • 计算机视觉:轨迹预测综述
  • 三维跨孔电磁波CT数据可视化框架搭建
  • OC和Swift混编,导入头文件‘xxx-Swift.h‘ file not found
  • 一文读懂HOOPS Native平台:快速开发桌面端、移动端3D应用程序!
  • Scrum工作模式及Scrum工具
  • [ros][ubuntu]ros在ubuntu18.04上工作空间创建和发布一个话题
  • 我的区块链笔记
  • Spring事务(ACID特性、隔离级别、传播机制、失效场景)
  • 机器学习笔记之最优化理论与方法(六)无约束优化问题——最优性条件
  • E5061B/是德科技keysight E5061B网络分析仪
  • 2.4 PE结构:节表详细解析
  • Vue2项目练手——通用后台管理项目第五节
  • 软件工程学术顶会——ESEC/FSE 2022 议题(网络安全方向)清单、摘要与总结
  • 从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
  • C++信息学奥赛1187:统计字符数
  • 计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析
  • vscode上搭建go开发环境
  • 10.(Python数模)(预测模型二)LSTM回归网络(1→1)
  • mac常见问题(五) Mac 无法开机
  • WebSocket与SSE区别
  • Qt鼠标点击事件处理:显示鼠标点击位置(完整示例)
  • OpenCV:实现图像的负片
  • HZOJ#237. 递归实现排列型枚举
  • C++ PIMPL 编程技巧