2 条题解
-
0
分块新技能 。
#include<bits/stdc++.h> using namespace std; const int N=1e5+10,M=1010,P=10007; int a[N],tag1[M],tag2[M],n,B; void pushdown(int x) { int bl=(x-1)*B+1,br=min(n,x*B); for(int i=bl;i<=br;i++)a[i]=(a[i]*tag2[x]+tag1[x])%P; tag1[x]=0,tag2[x]=1; } void upd1(int l,int r,int x) { int bl=(l-1)/B+1,br=(r-1)/B+1; if(bl==br) { pushdown(bl); for(int i=l;i<=r;i++) a[i]=(a[i]+x)%P; } else { pushdown(bl);pushdown(br); for(int i=l;i<=bl*B;i++)a[i]=(a[i]+x)%P; for(int i=(br-1)*B+1;i<=r;i++)a[i]=(a[i]+x)%P; for(int i=bl+1;i<br;i++)tag1[i]=(tag1[i]+x)%P; } } void upd2(int l,int r,int x) { int bl=(l-1)/B+1,br=(r-1)/B+1; if(bl==br) { pushdown(bl); for(int i=l;i<=r;i++) a[i]=a[i]*x%P; } else { pushdown(bl);pushdown(br); for(int i=l;i<=bl*B;i++)a[i]=a[i]*x%P; for(int i=(br-1)*B+1;i<=r;i++)a[i]=a[i]*x%P; for(int i=bl+1;i<br;i++) { tag1[i]=tag1[i]*x%P; tag2[i]=tag2[i]*x%P; } } } signed main() { cin>>n;B=sqrt(n); for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=(n-1)/B+1;i++)tag2[i]=1; for(int i=1;i<=n;i++) { int op,l,r,c;cin>>op>>l>>r>>c; if(op==0)upd1(l,r,c); if(op==1)upd2(l,r,c); if(op==2)pushdown((r-1)/B+1),cout<<a[r]<<"\n"; } return 0; } -
0
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e5 + 10, sqrtN = 350, MOD = 10007; // 区间加法,区间乘法,单点查询 // a[i]记录每个点的值,b[i]记录每个点i所在块; // add_tag[i]记录第i个块的加法标记,mul_tag[i]记录第i个块的乘法标记 // 每个块i的左端点L[i]、右端点R[i] int n, a[N], b[N], L[sqrtN], R[sqrtN], add_tag[sqrtN], mul_tag[sqrtN]; void push_down(int x) { // 下传第x个块的标记 for (int i = L[x]; i <= R[x]; i++) { a[i] = (a[i] * mul_tag[x] + add_tag[x]) % MOD; } mul_tag[x] = 1; add_tag[x] = 0; } signed main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; a[i] %= MOD; } int B = sqrt(n), cnt = (n + B - 1) / B; // B为每块的长度,cnt为总块数 for (int i = 1; i <= n; i++) { b[i] = (i - 1) / B + 1; } for (int i = 1; i <= cnt; i++) { L[i] = (i - 1) * B + 1; R[i] = min(i * B, n); } memset(add_tag, 0, sizeof(add_tag)); for (int i = 1; i <= cnt; i++) mul_tag[i] = 1; for (int i = 1; i <= n; i++) { int op, l, r, c; cin >> op >> l >> r >> c; if (op == 0) { // 区间加 if (b[l] == b[r]) { // 如果l和r在同一块内 push_down(b[l]); for (int j = l; j <= r; j++) a[j] = (a[j] + c) % MOD; } else { push_down(b[l]); for (int j = l; j <= R[b[l]]; j++) a[j] = (a[j] + c) % MOD; for (int j = b[l] + 1; j <= b[r] - 1; j++) add_tag[j] = (add_tag[j] + c) % MOD; push_down(b[r]); for (int j = L[b[r]]; j <= r; j++) a[j] = (a[j] + c) % MOD; } } else if (op == 1) { // 区间乘 if (b[l] == b[r]) { // 如果l和r在同一块内 push_down(b[l]); for (int j = l; j <= r; j++) a[j] = (a[j] * c) % MOD; } else { push_down(b[l]); for (int j = l; j <= R[b[l]]; j++) a[j] = (a[j] * c) % MOD; for (int j = b[l] + 1; j <= b[r] - 1; j++) { mul_tag[j] = (mul_tag[j] * c) % MOD; add_tag[j] = (add_tag[j] * c) % MOD; } push_down(b[r]); for (int j = L[b[r]]; j <= r; j++) a[j] = (a[j] * c) % MOD; } } else { // 单点查询 cout << (a[r] * mul_tag[b[r]] + add_tag[b[r]]) % MOD << '\n'; } } return 0; }
- 1
信息
- ID
- 475
- 时间
- 500ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 23
- 已通过
- 12
- 上传者