2 条题解
-
0
#include<bits/stdc++.h> using namespace std; #define int long long const int N=1e6+10,M=1010; int a[N],s1[N],s2[N],tag[N],n,B; void pushdown(int x) { int bl=(x-1)*B+1,br=min(x*B,n); for(int i=bl;i<=br;i++)a[i]=a[i]+tag[x]; tag[x]=0; } void upd(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++) { s1[bl]-=a[i]*a[i]; a[i]+=x;s2[bl]+=x; s1[bl]+=a[i]*a[i]; } } else { pushdown(bl); for(int i=l;i<=bl*B;i++) { s1[bl]-=a[i]*a[i]; a[i]+=x;s2[bl]+=x; s1[bl]+=a[i]*a[i]; } pushdown(br); for(int i=(br-1)*B+1;i<=r;i++) { s1[br]-=a[i]*a[i]; a[i]+=x;s2[br]+=x; s1[br]+=a[i]*a[i]; } for(int i=bl+1;i<br;i++) { s1[i]+=2*x*s2[i]+B*x*x; s2[i]+=B*x; tag[i]+=x; } } } int query(int l,int r) { int bl=(l-1)/B+1,br=(r-1)/B+1,ans=0; if(bl==br) { pushdown(bl); for(int i=l;i<=r;i++)ans+=a[i]*a[i]; } else { pushdown(bl); for(int i=l;i<=bl*B;i++)ans+=a[i]*a[i]; pushdown(br); for(int i=(br-1)*B+1;i<=r;i++)ans+=a[i]*a[i]; for(int i=bl+1;i<br;i++)ans+=s1[i]; } return ans; } signed main() { int q;cin>>n>>q;B=sqrt(n); for(int i=1;i<=n;i++) { cin>>a[i]; s1[(i-1)/B+1]+=a[i]*a[i]; s2[(i-1)/B+1]+=a[i]; } while(q--) { int op,l,r,c;cin>>op>>l>>r; if(op==0)cin>>c,upd(l,r,c); else cout<<query(l,r)<<'\n'; } return 0; } -
0
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e6 + 10, sqrtN = 1050; // 区间加,区间求平方和 // a[i]记录每个点的值,b[i]记录每个点i所在块; // sum1[i]记录第i个块的一次方和,sum2[i]记录第i个块的平方和 // 每个块i的左端点L[i]、右端点R[i], 块内标记tag[i] int n, m, a[N], b[N], L[sqrtN], R[sqrtN], tag[sqrtN], sum1[sqrtN], sum2[sqrtN]; void push_down(int x) { // 下传第x个块的标记 if (tag[x]) { for (int i = L[x]; i <= R[x]; i++) a[i] += tag[x]; tag[x] = 0; } } void calc(int x) { // 重新计算第x个块的sum1和sum2 sum1[x] = 0; sum2[x] = 0; for (int i = L[x]; i <= R[x]; i++) { sum1[x] += a[i]; sum2[x] += a[i] * a[i]; } } signed main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i]; } 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); calc(i); } memset(tag, 0, sizeof(tag)); for (int i = 1; i <= m; i++) { int op, l, r, c; cin >> op >> l >> r; if (op == 0) { cin >> c; if (b[l] == b[r]) { // 如果l和r在同一块内 push_down(b[l]); for (int j = l; j <= r; j++) a[j] += c; calc(b[l]); } else { push_down(b[l]); for (int j = l; j <= R[b[l]]; j++) a[j] += c; calc(b[l]); for (int j = b[l] + 1; j <= b[r] - 1; j++) { sum2[j] += 2 * c * sum1[j] + (R[j] - L[j] + 1) * c * c; sum1[j] += (R[j] - L[j] + 1) * c; tag[j] += c; } push_down(b[r]); for (int j = L[b[r]]; j <= r; j++) a[j] += c; calc(b[r]); } } else { int ans = 0; if (b[l] == b[r]) { // 如果l和r在同一块内 for (int j = l; j <= r; j++) { int val = a[j] + tag[b[l]]; ans += val * val; } } else { for (int j = l; j <= R[b[l]]; j++) { int val = a[j] + tag[b[l]]; ans += val * val; } for (int j = b[l] + 1; j <= b[r] - 1; j++) { ans += sum2[j]; } for (int j = L[b[r]]; j <= r; j++) { int val = a[j] + tag[b[r]]; ans += val * val; } } cout << ans << '\n'; } } return 0; }
- 1
信息
- ID
- 478
- 时间
- 3000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- 递交数
- 29
- 已通过
- 9
- 上传者