2 条题解
-
0
#include<bits/stdc++.h> using namespace std; #define int long long const int N=2e5+10,M=1010; int a[N],s[M],mx[M],n,B; void upd(int l,int r) { int bl=(l-1)/B+1,br=(r-1)/B+1; if(bl==br) { for(int i=l;i<=r;i++) s[bl]-=a[i],a[i]=sqrt(a[i]),s[bl]+=a[i]; mx[bl]=0; for(int i=(bl-1)*B+1;i<=min(n,bl*B);i++) mx[bl]=max(mx[bl],a[i]); } else { for(int i=l;i<=bl*B;i++) s[bl]-=a[i],a[i]=sqrt(a[i]),s[bl]+=a[i]; mx[bl]=0; for(int i=(bl-1)*B+1;i<=bl*B;i++) mx[bl]=max(mx[bl],a[i]); for(int i=(br-1)*B+1;i<=r;i++) s[br]-=a[i],a[i]=sqrt(a[i]),s[br]+=a[i]; mx[br]=0; for(int i=(br-1)*B+1;i<=min(n,br*B);i++) mx[br]=max(mx[br],a[i]); for(int i=bl+1;i<br;i++)if(mx[i]>1) { for(int j=(i-1)*B+1;j<=i*B;j++) s[i]-=a[j],a[j]=sqrt(a[j]),s[i]+=a[j]; mx[i]=0; for(int j=(i-1)*B+1;j<=i*B;j++) mx[i]=max(mx[i],a[j]); } } } int query(int l,int r) { int bl=(l-1)/B+1,br=(r-1)/B+1,ans=0; if(bl==br) { for(int i=l;i<=r;i++) ans+=a[i]; } else { for(int i=l;i<=bl*B;i++)ans+=a[i]; for(int i=(br-1)*B+1;i<=r;i++)ans+=a[i]; for(int i=bl+1;i<br;i++)ans+=s[i]; } return ans; } signed main() { cin>>n;B=sqrt(n); for(int i=1;i<=n;i++)cin>>a[i],s[(i-1)/B+1]+=a[i],mx[(i-1)/B+1]=max(mx[(i-1)/B+1],a[i]); for(int i=1;i<=n;i++) { int op,l,r,c;cin>>op>>l>>r>>c; if(op==0)upd(l,r); else cout<<query(l,r)<<'\n'; } return 0; } -
0
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 5e4 + 10, sqrtN = 250; // 区间开方,区间求和 // a[i]记录每个点的值,b[i]记录每个点i所在块; // sum[i]记录第i个块的元素和,mx[i]记录第i个块的最大值 // 每个块i的左端点L[i]、右端点R[i] int n, a[N], b[N], L[sqrtN], R[sqrtN], sum[sqrtN], mx[sqrtN]; 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]; } int B = sqrt(n), cnt = (n + B - 1) / B; // B为每块的长度,cnt为总块数 for (int i = 1; i <= n; i++) { b[i] = (i - 1) / B + 1; } memset(sum, 0, sizeof(sum)); memset(mx, 0, sizeof(mx)); for (int i = 1; i <= cnt; i++) { L[i] = (i - 1) * B + 1; R[i] = min(i * B, n); for (int j = L[i]; j <= R[i]; j++) { sum[i] += a[j]; mx[i] = max(mx[i], a[j]); } } 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在同一块内 if (mx[b[l]] <= 1) continue; // 块内最大值<=1,无需操作 for (int j = l; j <= r; j++) { sum[b[l]] -= a[j]; a[j] = sqrt(a[j]); sum[b[l]] += a[j]; } mx[b[l]] = 0; for (int j = L[b[l]]; j <= R[b[l]]; j++) mx[b[l]] = max(mx[b[l]], a[j]); } else { if (mx[b[l]] > 1) { for (int j = l; j <= R[b[l]]; j++) { sum[b[l]] -= a[j]; a[j] = sqrt(a[j]); sum[b[l]] += a[j]; } mx[b[l]] = 0; for (int j = L[b[l]]; j <= R[b[l]]; j++) mx[b[l]] = max(mx[b[l]], a[j]); } for (int j = b[l] + 1; j <= b[r] - 1; j++) { if (mx[j] <= 1) continue; // 块内最大值<=1,无需操作 for (int k = L[j]; k <= R[j]; k++) { sum[j] -= a[k]; a[k] = sqrt(a[k]); sum[j] += a[k]; } mx[j] = 0; for (int k = L[j]; k <= R[j]; k++) mx[j] = max(mx[j], a[k]); } if (mx[b[r]] > 1) { for (int j = L[b[r]]; j <= r; j++) { sum[b[r]] -= a[j]; a[j] = sqrt(a[j]); sum[b[r]] += a[j]; } mx[b[r]] = 0; for (int j = L[b[r]]; j <= R[b[r]]; j++) mx[b[r]] = max(mx[b[r]], a[j]); } } } else { int ans = 0; if (b[l] == b[r]) { // 如果l和r在同一块内 for (int j = l; j <= r; j++) ans += a[j]; } else { for (int j = l; j <= R[b[l]]; j++) ans += a[j]; for (int j = b[l] + 1; j <= b[r] - 1; j++) ans += sum[j]; for (int j = L[b[r]]; j <= r; j++) ans += a[j]; } cout << ans << '\n'; } } return 0; }
- 1
信息
- ID
- 473
- 时间
- 500ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 29
- 已通过
- 12
- 上传者