KANO07 @ 2024-02-07 14:31:27
下文的init函数,要是直接写到main里ac,单独写个init就0分
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
const int M = 1000;
int st[N], ed[N], a[N], pos[N];
int add[M], sum[M]; //add[i]第i块的增量标记
int t,n;
void init(){
for(int i = 1; i <= t; i++){
for(int j = st[i]; j <= ed[i]; j++){
sum[i] += a[j]; //sum第i块区间和
}
}
}
//处理碎片改sum,处理整块改add
void change(int l, int r, int d){
int p = pos[l], q = pos[r];
if(p == q){ //同一块,即碎片情况
for(int i = l; i <= r; i++){
a[i] += d;
}
sum[p] += d * (r - l + 1);
}else{ //多块,整块情况
for(int i = p + 1; i <= q - 1; i++){ //整块
add[i] += d;
}
for(int i = l; i <= ed[p]; i++){ //第一碎片
a[i] += d;
}
sum[p] += d * (ed[p] - l + 1);
for(int i = st[q]; i <= r; i++){ //最后碎片
a[i] += d;
}
sum[q] += d * (r - st[q] + 1);
}
return;
}
long long ask(int l, int r){
int p = pos[l], q = pos[r];
long long ans = 0;
if(p == q){
for(int i = l; i <= r; i++){
ans += a[i];
}
ans += add[p] * (r - l + 1);
}else{
for(int i = p + 1; i <= q - 1; i++){
ans += sum[i] + add[i] * (ed[i] - st[i] + 1);
}
for(int i = l; i <= ed[p]; i++){
ans += a[i];
}
ans += add[p] * (ed[p] - l + 1);
for(int i = st[q]; i <= r; i++){
ans += a[i];
}
ans += add[q] * (r - st[q] + 1);
}
return ans;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int m;
cin>>n>>m;
int block = sqrt(n); //块的大小
int t = n/block; //块的数量
if(n % block != 0) t++;
for(int i = 1; i <= t; i++){
st[i] = (i - 1) * block + 1; //各块起点
ed[i] = i*block; //各块终点
}
ed[t] = n; //最后一块终点调整一下
for(int i = 1; i <= n; i++){
pos[i] = (i-1)/block + 1; //各点位于的块
}
for(int i = 1; i <= n; i++){
cin>>a[i];
}
init();
while(m--){
int jud;
cin>>jud;
if(jud == 1){
int x,y,k;
cin>>x>>y>>k;
change(x, y, k);
}else{
int x,y;
cin>>x>>y;
cout<<ask(x, y)<<endl;
}
}
return 0;
}
直接写到main里
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
const int M = 1000;
int st[N], ed[N], a[N], pos[N];
int add[M], sum[M]; //add[i]第i块的增量标记
int t,n;
//处理碎片改sum,处理整块改add
void change(int l, int r, int d){
int p = pos[l], q = pos[r];
if(p == q){ //同一块,即碎片情况
for(int i = l; i <= r; i++){
a[i] += d;
}
sum[p] += d * (r - l + 1);
}else{ //多块,整块情况
for(int i = p + 1; i <= q - 1; i++){ //整块
add[i] += d;
}
for(int i = l; i <= ed[p]; i++){ //第一碎片
a[i] += d;
}
sum[p] += d * (ed[p] - l + 1);
for(int i = st[q]; i <= r; i++){ //最后碎片
a[i] += d;
}
sum[q] += d * (r - st[q] + 1);
}
return;
}
long long ask(int l, int r){
int p = pos[l], q = pos[r];
long long ans = 0;
if(p == q){
for(int i = l; i <= r; i++){
ans += a[i];
}
ans += add[p] * (r - l + 1);
}else{
for(int i = p + 1; i <= q - 1; i++){
ans += sum[i] + add[i] * (ed[i] - st[i] + 1);
}
for(int i = l; i <= ed[p]; i++){
ans += a[i];
}
ans += add[p] * (ed[p] - l + 1);
for(int i = st[q]; i <= r; i++){
ans += a[i];
}
ans += add[q] * (r - st[q] + 1);
}
return ans;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int m;
cin>>n>>m;
int block = sqrt(n); //块的大小
int t = n/block; //块的数量
if(n % block != 0) t++;
for(int i = 1; i <= t; i++){
st[i] = (i - 1) * block + 1; //各块起点
ed[i] = i*block; //各块终点
}
ed[t] = n; //最后一块终点调整一下
for(int i = 1; i <= n; i++){
pos[i] = (i-1)/block + 1; //各点位于的块
}
for(int i = 1; i <= n; i++){
cin>>a[i];
}
for(int i = 1; i <= t; i++){
for(int j = st[i]; j <= ed[i]; j++){
sum[i] += a[j]; //sum第i块区间和
}
}
while(m--){
int jud;
cin>>jud;
if(jud == 1){
int x,y,k;
cin>>x>>y>>k;
change(x, y, k);
}else{
int x,y;
cin>>x>>y;
cout<<ask(x, y)<<endl;
}
}
return 0;
}
by YDMaYi @ 2024-02-07 14:52:27
-wall打开试试
by As_Snow @ 2024-02-07 14:53:21
@KANO07
int t = n/block; //块的数量
by As_Snow @ 2024-02-07 14:55:43
你在主函数里重新定义了一个 t
by KANO07 @ 2024-02-07 14:58:39
@As_Snow 感谢感谢