洛谷 B3645 数列前缀和 2 题解
前缀知识:枚举,费马小定理,逆元,线性乘法逆元,线段树(?)。
解法1:暴力
如题。暴力枚举即可,30分。由于太简单,不给代码。
解法2:前缀积+费马小定理+逆元
由于涉及静态区间,可以想到前缀积。前缀积公式为
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,p=1145141;
int n,Q,a[N],q[N],ans;
int ksm(int a,int b){
int ans=1;
a%=p;
while(b){
if(b&1){
ans=ans*a%p;
}
a=a*a%p;
b>>=1;
}
return ans;
}
signed main(){
//freopen("xx.in","r",stdin);
//freopen("xx.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>Q;
q[0]=1;
for(int i=1;i<=n;i++){
cin>>a[i];
q[i]=q[i-1]*a[i]%p;
}
while(Q--){
int l,r;
cin>>l>>r;
ans^=(q[r]*ksm(q[l-1],p-2)%p);
}
cout<<ans;
return 0;
}
解法3:线性乘法逆元
由于
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,p=1145141;
int n,Q,a[N],q[N],c[p],ans;
int ksm(int a,int b){
int ans=1;
a%=p;
while(b){
if(b&1){
ans=ans*a%p;
}
a=a*a%p;
b>>=1;
}
return ans;
}
signed main(){
//freopen("xx.in","r",stdin);
//freopen("xx.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
c[1]=1;
for(int i=2;i<p;i++){
c[i]=c[p%i]*(p-p/i)%p;
}
cin>>n>>Q;
q[0]=1;
for(int i=1;i<=n;i++){
cin>>a[i];
q[i]=q[i-1]*a[i]%p;
}
while(Q--){
int l,r;
cin>>l>>r;
ans^=(q[r]*c[q[l-1]]%p);
}
cout<<ans;
return 0;
}
解法4:线段树
没错,由于是区间,所以我们的线段树来了!用线段树不需要任何的数论知识,这意味着不会数学的小学生都能做!线段树是万能的!(线段树做法纯属瞎搞,请勿模仿)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,p=1145141;
int n,q,a[N],t[N*4],ans;
void build(int now,int tl,int tr){
if(tl==tr){
t[now]=a[tl];
return ;
}
int mid=(tl+tr)/2;
build(now*2,tl,mid);
build(now*2+1,mid+1,tr);
t[now]=t[now*2]*t[now*2+1]%p;
}
int query(int now,int tl,int tr,int l,int r){
if(tl>=l&&tr<=r){
return t[now];
}
if(tl>r||tr<l){
return 1;
}
int mid=(tl+tr)/2;
return query(now*2,tl,mid,l,r)*query(now*2+1,mid+1,tr,l,r)%p;
}
signed main(){
//freopen("xx.in","r",stdin);
//freopen("xx.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(q--){
int l,r;
cin>>l>>r;
ans^=query(1,1,n,l,r);
}
cout<<ans;
return 0;
}
总结
此题的做法很多,最好的一种是线段树,算是一个比较模板的题,所以没有太多讲解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?