线段树
(CodeVS:1082)
C++指针版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include <iostream> #include <cstdio> #include <cstring> #define ll long long using namespace std; struct rec{ ll l,r,delta,sum; rec *lc,*rc; }; rec *root; ll l,r,add,n,m,tmp; void update(rec *now,ll l,ll r,ll add) { if ((l<=now->l)&&(now->r<=r)) { now->delta+=add; return ; } if (l<=(now->l+now->r)/2) update(now->lc,l,r,add); if (r>(now->l+now->r)/2) update(now->rc,l,r,add); now->sum=now->lc->sum+(now->lc->r-now->lc->l+1)*now->lc->delta; now->sum+=now->rc->sum+(now->rc->r-now->rc->l+1)*now->rc->delta; } void build(rec *now,ll l,ll r) { now->l=l;now->r=r; if (l==r) { scanf ( "%lld" ,&now->sum); now->lc=NULL;now->rc=NULL; return ; } now->lc= new rec; now->rc= new rec; build(now->lc,l,(l+r)/2); build(now->rc,(l+r)/2+1,r); now->sum=now->lc->sum+now->rc->sum; } ll query(rec *now,ll l,ll r) { ll ret=0; if ((l<=now->l)&&(now->r<=r)) return now->sum+now->delta*(now->r-now->l+1); now->lc->delta+=now->delta; now->rc->delta+=now->delta; now->sum+=now->delta*(now->r-now->l+1); now->delta=0; if (l<=(now->l+now->r)/2)ret=query(now->lc,l,r); if (r>(now->r+now->l)/2)ret+=query(now->rc,l,r); return ret; } int main() { root= new rec; scanf ( "%lld" ,&n); build(root,1,n); scanf ( "%lld" ,&m); for ( int i=1;i<=m;i++) { scanf ( "%lld" ,&tmp); if (tmp==1) { scanf ( "%lld %lld %lld" ,&l,&r,&add); update(root,l,r,add); } if (tmp==2) { scanf ( "%lld %lld" ,&l,&r); printf ( "%lld\n" ,query(root,l,r)); } } } |
指针+读入优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include <iostream> #include <cstdio> #include <cstring> #define ll long long using namespace std; struct rec{ ll delta,sum,l,r; rec *lc,*rc; }; rec *root; ll l,r,add,n,m,tmp; void read(ll &k) { int f=1; char c= getchar ();k=0; while (c< '0' ||c> '9' ) c== '-' &&(f=-1),c= getchar (); while (c>= '0' &&c<= '9' )k=k*10+c- '0' ,c= getchar (); k*=f; } void build(rec *now,ll l,ll r) { now->l=l;now->r=r; if (l==r){read(now->sum); return ;} now->lc= new rec; now->rc= new rec; build(now->lc,l,(l+r)>>1); build(now->rc,((l+r)>>1)+1,r); now->sum=now->lc->sum+now->rc->sum; } void update(rec *now,ll l,ll r,ll add) { if ((l<=now->l)&&(now->r<=r)){now->delta+=add; return ;} if (l<=(now->l+now->r)>>1) update(now->lc,l,r,add); if (r>(now->l+now->r)>>1) update(now->rc,l,r,add); now->sum=now->lc->sum+(now->lc->r-now->lc->l+1)*now->lc->delta; now->sum+=now->rc->sum+(now->rc->r-now->rc->l+1)*now->rc->delta; } ll query(rec *now,ll l,ll r) { if ((l<=now->l)&&(now->r<=r)) return now->sum+now->delta*(now->r-now->l+1); ll ret=0; now->lc->delta+=now->delta; now->rc->delta+=now->delta; now->sum+=now->delta*(now->r-now->l+1); now->delta=0; if (l<=(now->l+now->r)>>1)ret=query(now->lc,l,r); if (r>(now->r+now->l)>>1)ret+=query(now->rc,l,r); return ret; } int main() { root= new rec; read(n); build(root,1,n); scanf ( "%lld" ,&m); for ( int i=1;i<=m;i++) { scanf ( "%lld" ,&tmp); if (tmp==1) { read(l);read(r);read(add); update(root,l,r,add); } if (tmp==2) { read(l);read(r); printf ( "%lld\n" ,query(root,l,r)); } } } |
数组模拟+读入优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include <iostream> #include <cstdio> #include <algorithm> #define ll long long using namespace std; ll n,m,l,r,tmp,add; const int maxn=200000; ll le[maxn*4],ri[maxn*4],delta[maxn*4],sum[maxn*4]; void read(ll &k) { k=0;ll f=1; char c= getchar (); while (c< '0' ||c> '9' )c== '-' &&(f=-1),c= getchar (); while (c>= '0' &&c<= '9' )k=k*10+c- '0' ,c= getchar (); k*=f; } void build(ll l,ll r,ll cur) { le[cur]=l;ri[cur]=r; if (l==r){read(sum[cur]); return ;} build(l,(l+r)>>1,cur*2); build(((l+r)>>1)+1,r,cur*2+1); sum[cur]=sum[cur*2]+sum[cur*2+1]; } ll query(ll l,ll r,ll cur) { if (l<=le[cur]&&ri[cur]<=r) return sum[cur]+delta[cur]*(ri[cur]-le[cur]+1); ll ret=0; delta[cur*2]+=delta[cur]; delta[cur*2+1]+=delta[cur]; sum[cur]+=delta[cur]*(ri[cur]-le[cur]+1); delta[cur]=0; if (l<=(le[cur]+ri[cur])>>1)ret=query(l,r,cur*2); if (r>(le[cur]+ri[cur])>>1)ret+=query(l,r,cur*2+1); return ret; } void update(ll l,ll r,ll add,ll cur) { if (l<=le[cur]&&r>=ri[cur]){delta[cur]+=add; return ;} if (l<=(le[cur]+ri[cur])>>1)update(l,r,add,cur*2); if (r>(le[cur]+ri[cur])>>1)update(l,r,add,cur*2+1); sum[cur]=sum[cur*2]+delta[cur*2]*(ri[cur*2]-le[cur*2]+1); sum[cur]+=sum[cur*2+1]+delta[cur*2+1]*(ri[cur*2+1]-le[cur*2+1]+1); } int main() { read(n); build(1,n,1); read(m); for ( int i=0;i<m;i++) { read(tmp); if (tmp==1) { read(l);read(r);read(add); update(l,r,add,1); } if (tmp==2) { read(l);read(r); printf ( "%lld\n" ,query(l,r,1)); } } } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· C# 13 中的新增功能实操
· Vue3封装支持Base64导出的电子签名组件
· 万字长文详解Text-to-SQL
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)