Rt,我的思路就是判断块内的是否都为1,如果不是就暴力修改。
这是我的代码:
#include <cstdio>
#include <iostream>
#include <cmath>
#define int long long
using namespace std;
const int maxn = 1e5 + 1;
int n, m, opt, x, y, num, len, bl, br, tmp;
int L[251], R[251], cnt[251], dwy[251], sum[251], a[maxn], belong[maxn];
void init(){
len = sqrt(n);
num = len;
for (int i = 1; i <= num; i++){
L[i] = (i - 1) * len + 1;
R[i] = i * len;
}
if (R[num] < n){
num++;
L[num] = R[num - 1] + 1;
R[num] = n;
}
for (int i = 1; i <= num; i++){
for (int j = L[i]; j <= R[i]; j++){
if (a[j] <= 1) cnt[i]++;
belong[j] = i;
sum[i] += a[j];
}
}
}
int query1(int l, int r){
int ans = 0;
bl = belong[l];
br = belong[r];
if (bl == br){
for (int i = l; i <= r; i++){
ans += a[i];
}
return ans;
}else{
for (int i = l; i <= R[bl]; i++){
ans += a[i];
}
for (int i = bl + 1; i <= br - 1; i++){
ans += sum[i];
}
for (int i = L[br]; i <= r; i++){
ans += a[i];
}
return ans;
}
}
void query0(int l, int r){
bl = belong[l];
br = belong[r];
if (bl == br){
if (sum[bl] <= R[bl] - L[bl] + 1) return;
for (int i = l; i <= r; i++){
if (a[i] > 1){
tmp = a[i];
a[i] = sqrt(a[i]);
sum[bl] -= (tmp - a[i]);
}
}
}else{
if (sum[bl] > R[bl] - L[bl] + 1){
for (int i = l; i <= R[bl]; i++){
if (a[i] > 1){
tmp = a[i];
a[i] = sqrt(a[i]);
sum[bl] -= (tmp - a[i]);
}
}
}
for (int i = bl + 1; i <= br - 1; i++){
if (sum[i] <= R[i] - L[i] + 1) continue;
for (int j = L[i]; j <= R[i]; j++){
if (a[j] > 1){
tmp = a[j];
a[j] = sqrt(a[j]);
sum[i] -= (tmp - a[j]);
}
}
}
if (sum[br] > R[br] - L[br] + 1){
for (int i = L[br]; i <= r; i++){
if (a[i] > 1){
tmp = a[i];
a[i] = sqrt(a[i]);
sum[br] -= (tmp - a[i]);
}
}
}
}
}
signed main(){
scanf("%lld", &n);
for (int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
}
init();
scanf("%lld", &m);
for (int i = 1; i <= m; i++){
scanf("%lld%lld%lld", &opt, &x, &y);
if (x > y) swap(x, y);
if (opt == 0) query0(x, y);
else printf("%lld\n", query1(x, y));
}
return 0;
}
交上去之后是50分,后面的数据T飞了。然后去讨论区看到一个远古帖说要开大数组,然后我把数组开大了一倍,就过了!而且最慢的点也不到100ms!可是很明显代码里不存在数组越界的情况,为什么开大数组会快这么多?