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

一些 DS 题目

1.nfls #1194 3的倍数区间

题意

给定一个长度为的数组,有次修改,每次把数组中某个元素改成其他的数或者询问一个区间中有多少个子区间满足和为 \(3\) 的倍数。

\(n,m\le 3\times 10^5\)

思路

和为倍数的,得先想到把余数分类开来,反正这里余数只有 \(0,1,2\)

注意到题目问的是子区间的个数。联想到维护最大子段和的思路:在线段树上维护区间的和、前缀和、后缀和、子段和答案。

于是同样考虑,维护区间 \(\bmod 3\) 的和 \(sum\)、前后缀余 \(0,1,2\) 的桶 l[],r[],以及区间答案 \(ans\),容易用两个桶维护 \(ans\),将余数和为 \(0\) 的合并,考虑合并函数:

node add(const node a,const node b)
{node ret;ret.sum=(a.sum+b.sum)%3;ret.ans=a.ans+b.ans+a.r[0]*b.l[0]+a.r[1]*b.l[2]+a.r[2]*b.l[1];//乘法原理计算方案数for(int i=0;i<3;i++){ret.l[i]+=a.l[i];ret.l[(i+a.sum)%3]+=b.l[i];//囊括一整段ls查看触及到rs的l端 ret.r[i]+=b.r[i];ret.r[(i+b.sum)%3]+=a.r[i];}	return ret;
}

对于单点修改直接对四者初始化,照线段树常例 pushupquery。平日里求和的 query 是可以直接相加,但是这里使用 add 函数,不能用一个全空的结构体变量参与运算,因此要把合并区间答案的给拎出来——对于返回结构体的 query,使用 add 合并区间答案的,都适用以下写法:

node query(ll u,ll l,ll r,ll ql,ll qr)
{if(ql<=l&&r<=qr)return T[u];ll mid=(l+r)>>1;if(qr<=mid)return query(ls,l,mid,ql,qr);if(ql>mid)return query(rs,mid+1,r,ql,qr);return add(query(ls,l,mid,ql,qr),query(rs,mid+1,r,ql,qr));}

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls u<<1
#define rs u<<1|1
const ll N=3e5+9;
ll n,Q;
ll a[N];
struct SegT
{struct node{ll sum;//模3区间和 ll ans;ll l[3]={0,0,0},r[3]={0,0,0};//前后缀和每个余数的桶 void init(ll k){sum=k%3;ans=(k%3==0);for(int i=0;i<3;i++)l[i]=r[i]=0;l[k%3]=r[k%3]=1;}}T[N<<2];node add(const node a,const node b){node ret;ret.sum=(a.sum+b.sum)%3;ret.ans=a.ans+b.ans+a.r[0]*b.l[0]+a.r[1]*b.l[2]+a.r[2]*b.l[1];for(int i=0;i<3;i++){ret.l[i]+=a.l[i];ret.l[(i+a.sum)%3]+=b.l[i];//囊括一整段ls查看触及到rs的l端 ret.r[i]+=b.r[i];ret.r[(i+b.sum)%3]+=a.r[i];}	return ret;}void pushup(ll u){T[u]=add(T[ls],T[rs]);}void build(ll u,ll l,ll r){if(l==r){T[u].init(a[l]);return;}ll mid=(l+r)>>1;build(ls,l,mid);build(rs,mid+1,r);pushup(u);}void modify(ll u,ll l,ll r,ll x,ll k){if(l==r){T[u].init(k);return;}ll mid=(l+r)>>1;if(x<=mid)modify(ls,l,mid,x,k);if(x>mid)modify(rs,mid+1,r,x,k);pushup(u);}node query(ll u,ll l,ll r,ll ql,ll qr){if(ql<=l&&r<=qr)return T[u];ll mid=(l+r)>>1;if(qr<=mid)return query(ls,l,mid,ql,qr);if(ql>mid)return query(rs,mid+1,r,ql,qr);return add(query(ls,l,mid,ql,qr),query(rs,mid+1,r,ql,qr));}
}A;
int main()
{scanf("%lld%lld",&n,&Q);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);A.build(1,1,n);while(Q--){ll op,l,r;scanf("%lld%lld%lld",&op,&l,&r);if(op==1)A.modify(1,1,n,l,r);else printf("%lld\n",A.query(1,1,n,l,r).ans);}return 0;
}
http://www.aitangshan.cn/news/519.html

相关文章:

  • 虚弱相关-【改错】-下
  • 这一次,国产全自研高性能图形GPU真的来了
  • 一文彻底讲透:AI大模型应用架构全解析
  • 读开源项目成功之道11开源项目落幕
  • 2025未来科学大奖揭晓!每人奖金约720万元
  • Dataclass
  • 计算机基础之编程
  • WRC观点:人形机器人五大爆发趋势
  • dotnet X11 获取多屏 edid 信息
  • SEO 快速流量见效的方式-新词
  • 揭开红血球双凹碟形之谜
  • OVS配置CookBook
  • 推荐7本书《MLIR编译器原理与实践》、《ONNX人工智能技术与开发实践》、《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》
  • 打开手机 设置:搜索快应用管理--打开,删除其中不是自己安装的APP,可能有好多不是自己安装的
  • 递归因果发现算法与Python实现
  • 镜像地址相关
  • 军用警用无线电加密算法存在严重漏洞,可被轻易破解
  • Mybatis-Plus的InnerInterceptor插件之beforeQuery方法
  • 第二十一天
  • 有限状态自动机理论
  • Mybatis-Plus的InnerInterceptor插件之beforeQuery()
  • xz pixz 的多线程解压缩方法 - tsunchi
  • 苹果容器Apple container是做什么用的?
  • kubernetes-1.32高可用集群部署(kubeadm)
  • 安装pandas和openpyxl
  • pandas用法
  • 第三章 训练初步深入(3)
  • 安装pandas
  • 奥林匹克小丛书小蓝本习题另解或加强(数论卷)(一)
  • 关于磁盘io性能的命令