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

牛客周赛113

(0条未读通知) 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ

E题

首先我们预处理每个数组从\(n\)个数中选择\(i\)个数,其和模495为\(j\)的方案数,可以使用三维\(dp[i][j][k]\)数组表示前\(i\)个数中选\(j\)个数,他们的和对495取模为\(k\)的方案数,初始化\(dp[0][0][0]=1\),可以写出转移方程:

\[dp[i][j][k]=\begin{cases}dp[i-1][j][k]&j=0,\\dp[i-1][j][k]+dp[i-1][j-1][(k-a[i]+495)\%495]&else.\end{cases} \]

这里我们可以使用滚动数组优化掉第一维,用\(dp[i][j]\)表示从\(n\)个数中选\(i\)个数,其和模495为\(j\)的方案数。

vector<vector<int>> dp(n+1,vector<int>(m,0));dp[0][0]=1;for(int i=1;i<=n;i++){auto ndp=dp;for(int j=1;j<=n;j++){for(int k=0;k<m;k++){int v=(a[i]+k)%m;ndp[j][v]=(ndp[j][v]+dp[j-1][k])%mod;}}dp=ndp;}

之后我们将\(dpa\)\(dpb\)都求出来之和,因为后面求解答案时,我们要枚举\(a\)选了\(i\)个元素,那么\(b\)的贡献为\(\sum_{j=0}^{i}{dpb[j][k]}\),所以我们再对\(b\)求一个前缀和,\(dpb[i][j]\)表示至多选\(i\)个元素时,他们的和模495为\(j\)的方案数之和。

for(int j=0;j<m;j++){for(int i=1;i<=n;i++){dpb[i][j]=(dpb[i-1][j]+dpb[i][j])%mod;}
}

这样我们就可以求解答案了,枚举从\(a\)中选择的个数\(i\),枚举\(a\)模495为\(j\),枚举\(b\)模495为\(k\),那么答案为:

vector<int> ans(m,0);for(int i=0;i<=n;i++){for(int j=0;j<m;j++){if(dpa[i][j]==0) continue;for(int k=0;k<m;k++){if(dpb[i][k]==0) continue;int v=(j+k)%m;ans[v]=(ans[v]+dpa[i][j]*dpb[i][k]%mod)%mod;}}}

但是wa掉了,只过了25%,太构思了,检查很多遍了。

不如先写F

这个提交非常不错,值得学习。

(0条未读通知) 代码查看

F题

给定一个长度为\(n\)的数组,给定\(q\)个操作,执行两种操作:

  • \(1\space x\space y\):将数组的第\(x\)为修改为\(y\)
  • \(2\space l\space r\):查询在区间\([l,r]\)内任取两个元素,其乘积是495的倍数的方案数。

很明显可以看到操作涉及单点修改区间查询,所以我们可以考虑使用树状数组来维护信息。对于区间内任选两个数,其乘积要是495的倍数,那么我们可以对495的所有因数开一个树状数组,维护这个因数的倍数的出现次数。但是会有一个问题,比如\(105=3\times 5\times 7\),既是3的倍数,又是5的倍数,也是15的倍数,那么这个数肯定只能够被算一次,所以我们取\(g=gcd(a[i],495)\)作为\(a[i]\)贡献的因数,这样保证每个数\(a[i]\)一定只会被计算一次,这样我们就可以直接做了。

预处理495的因数以及下标映射:

const int m=495;
//fac[i]表示m的第i个因数,pm[i]表示m的因数i在fac数组中的下标
vector<int> fac(13),pm(m+1);
int tot=0;//计数
for(int i=1;i<=m;i++){if(m%i==0){fac[++tot]=i;pm[i]=tot;}
}

初始化:

vecotr<Fenwick> tr(13,Fenwick(n));
for(int i=1;i<=n;i++){int g=gcd(a[i],m);tr[pm[g]].update(i,1);
}

对于\(update\)操作:我们先将原来位置\(x\)\(a[x]\)的贡献撤销,再将\(a[x]:=y\),再加上\(a[x]\)的贡献。

int g=gcd(a[x],m);
tr[pm[g]].update(x,-1);
a[x]=y;
g=gcd(a[x],m);
tr[pm[g]].update(x,1);

对于\(query\)操作:我们用\(cnt[i]\)表示第\(i\)个因数的贡献次数,求出\(cnt\)数组;之后我们枚举不同的因数组合\((i,j)\),判断\(m\mid fac[i]\times fac[j]\),然后求\(cnt[i]\times cnt[j]\)贡献即可。两个注意点:(1)注意枚举时\(i\leq j\),避免重复统计;(2)\(i=j\)时,贡献为\(cnt[i]\times(cnt[i]-1)/2\)

vector<int> cnt(13,0);
for(int i=1;i<=12;i++){cnt[i]=tr[i].query(r)-tr[i].query(l-1);
}
int ans=0;
for(int i=1;i<=12;i++){for(int j=i;j<=12;j++){int g=gcd(fac[i]*fac[j],m);if(g==m){if(i==j) ans+=cnt[i]*(cnt[i]-1)/2;else ans+=cnt[i]*cnt[j];}}cout << ans << endl;
}

这样就解决问题了,树状数组模板为:

struct Fenwick {vector<int> sum;int n;Fenwick(int size) : n(size), sum(size + 2, 0) {}int lowbit(int x){return x&-x;}void update(int pos,int x){for(int i=pos;i<=n;i+=lowbit(i))sum[i]+=x;}int query(int pos){int res=0;for(int i=pos;i;i-=lowbit(i))res+=sum[i];return res;}void init(){for(int i=0;i<=n;i++){sum[i]=0;}}
};

法二:线段树+状压

大致思路是线段树的\(node\)节点为:

struct segment{int l,r;vector<int> cnt;//3 3 5 11//假如i=13=(1101),也就表示是3*3*11倍数的数,cnt[i]表示这个状态的个数//当然这里也是和m的最大公因数
}

因为有状压,所以我们还需要一个\(encode\)函数,用来对\(a[i]\)进行转化为状态。\(pushup\)函数就将\(cnt\)数组合并就行,因为是单点修改,我们不需要\(pushdown\)函数了,\(update\)函数就是一样的先将\(a[x]\)的贡献撤销,然后使用\(encode\)\(y\)进行转换,然后加上贡献。

最关键的就是\(query\)函数了,这个和区间合并是一样的,每次我们返回的是一个\(vector<int>cnt\)数组。然后在\(op=2\)中,我们得到了\(cnt\)数组之后,在枚举状态\((i,j)\)时,需要注意这两个状态表示的数的乘积能否被\(m\)整除,然后和第一种方法一样,统计答案就好。

http://www.jsqmd.com/news/13457/

相关文章:

  • 如何在统信系统中将 Avalonia 软件程序打包 Deb 安装包
  • 分组密码算法工作模式
  • 2025 年山西/在职研究生培训机构推荐榜:同等学力申硕培训机构,聚焦数智化与个性化学习新范式
  • 2025 年涡街流量计厂家推荐,湖北南控仪表科技有限公司技术创新与行业应用解决方案解析
  • 2025 年超声波流量计厂家推荐,湖北南控仪表科技有限公司产品技术与行业应用解决方案解析
  • ArcGIS 10.2.2 字符串长度为20却仅能输入3个汉字的解决方法
  • 2025 年涡轮流量计厂家推荐:湖北南控仪表科技有限公司设备供应与多行业适配解决方案
  • OAuth/OpenID Connect安全测试全指南
  • 采用虚幻引擎(UE5)打造黑夜场景氛围
  • 2025 年电磁流量计厂家推荐:湖北南控仪表科技有限公司专业设备供应与行业适配解决方案
  • 90%企业忽略的隐藏成本:Data Agent如何降低数据分析总拥有成本(TCO)
  • adb logcat 根据Tag 过滤日志
  • 详细介绍:Spring Boot 详细介绍
  • 2025 年艺术涂料厂家最新推荐排行榜,全方位呈现优质品牌特色与竞争力
  • 爬虫遇到的问题与解
  • 自动化测试框架选型指南:数据驱动、关键字驱动还是混合模式?
  • 直播软件搭建避坑!从直播源码选型到运维,3步搞定上线+降本60%
  • LatchUtils:简化Java异步任务同步的利器
  • Qoder + ADB Supabase :5分钟GET超火AI手办生图APP
  • 实验报告2
  • Agentic RAG对比传统RAG的优势
  • linux系统查看磁盘过程
  • 2025-10-14 闲话
  • ftp多用户多目录配置
  • 芋道框架怎么样
  • 超真实“电脑崩溃模拟器”:蓝屏、重启、FBI警告一应俱全!
  • (20)ASP.NET Core2.2 EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性) - 指南
  • (在构造函数中)调用super(props)的目的是什么?
  • 温故知新,机器人进化论,机器人分类与全球格局
  • Zemax:初学者的混合模式 - 指南