初始化封装到函数里就wa

P3372 【模板】线段树 1

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 感谢感谢


|