1 条题解
-
0
自动搬运
来自洛谷,原作者为

dream10
**搬运于
2025-08-24 22:47:07,当前版本为作者最后更新于2025-06-01 11:27:24,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
Preface
目前的两篇题解要么渐进复杂度不如我,要么常数不如我。
@happybob @Alex_Eon
Hint
两个数相加,最多进几位?
修改的本质是什么?
查询的时候除了对应位置的数值,还需要知道什么?
怎么快速计算进位?
Solution
Step 1
发现两个数相加,最多进一位。修改也不过是改 ,查询只需要知道比当前这一位低的数中是否进位。
于是用线段树维护这段区间的 ,表示是否被进位下是不是向前进位,合并直接复合。
难度不高,详见代码。
#include<bits/stdc++.h> using namespace std; int n,m; const int MAXN=100010; int a[MAXN]; int b[MAXN]; struct Node{ int d[2]; }t[MAXN<<2]; Node operator + (Node A,Node B){ Node C; C.d[0]=B.d[A.d[0]]; C.d[1]=B.d[A.d[1]]; return C; } #define mid ((L+R)>>1) void build(int x,int L=1,int R=n){ if(L==R){ t[x].d[0]=a[L]+b[L]+0>=10; t[x].d[1]=a[L]+b[L]+1>=10; }else{ build(x<<1,L,mid); build(x<<1|1,mid+1,R); t[x]=t[x<<1]+t[x<<1|1]; } } void upd(int x,int pos,int L=1,int R=n){ if(L==R){ t[x].d[0]=a[L]+b[L]+0>=10; t[x].d[1]=a[L]+b[L]+1>=10; }else{ if(pos<=mid)upd(x<<1,pos,L,mid); else upd(x<<1|1,pos,mid+1,R); t[x]=t[x<<1]+t[x<<1|1]; } } Node res; void qry(int x,int l,int r,int L=1,int R=n){ if(l<=L&&R<=r){ res=res+t[x]; }else{ if(l<=mid)qry(x<<1,l,r,L,mid); if(r>mid)qry(x<<1|1,l,r,mid+1,R); } } #undef mid signed main(){ cin>>n>>m; for(int i=2;i<=n;++i){ char c;cin>>c; a[i]=c-'0'; } for(int i=2;i<=n;++i){ char c;cin>>c; b[i]=c-'0'; } reverse(a+2,a+n+1); reverse(b+2,b+n+1); build(1); char op;int i,c; while(m--){ cin>>op>>i; ++i; if(op=='W'){ cin>>c; a[i]=c; upd(1,i); }else if(op=='Z'){ cin>>c; b[i]=c; upd(1,i); }else{ res.d[0]=0; res.d[1]=0; qry(1,1,i-1); printf("%d\n",(a[i]+b[i]+res.d[0])%10); } } return 0; }
- 1
信息
- ID
- 8571
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者