Submission #838308

#TimeUsernameProblemLanguageResultExecution timeMemory
838308Elvin_FritlAddk (eJOI21_addk)C++17
56 / 100
625 ms11188 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1e5 + 5;

int pre[N],suf[N];
int n,k;
int a[N];
long long tree[N*3];

void built(int v,int l,int r)
{
    if(l > r)
    {
        return;
    }
    if(l == r)
    {
        tree[v] = a[l];
        return;
    }
    int mid=(l+r)>>1;
    built(v*2,l,mid);
    built(v*2 + 1,mid+1,r);
    tree[v] = tree[v*2] + tree[v*2 + 1];
}

long long get(int v,int l,int r,int ml,int mr)
{
    if(l > r || ml > r || mr < l)
    {
        return 0;
    }
    if(ml <= l && r <= mr)
    {
        return tree[v];
    }
    int mid=(l+r)>>1;
    return get(v*2 , l , mid , ml , mr) + get(v*2 + 1,mid + 1,r,ml,mr);
}

long long prf(int l, int r){
    ///мы хотим посчитать 1 + 2 + 3... на подотрезке, возьмем преффиксную сумму на этом подотрезке
    long long sum = pre[r] - pre[l - 1];
    ///теперь отнимем сумму на подотрезке
    sum -= (l - 1) * (get(1, 1, n, l, r));
    return sum;
}

long long syf(int l, int r){
    ///полностью зеркальная функция
    long long sum = suf[l] - suf[r + 1];
    sum -= (n - r) * get(1, 1, n, l, r);
    return sum;
}

int32_t main(){
    cin>>n>>k;
    pre[0] = 0;
    suf[n+1] = 0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        pre[i] = pre[i-1] + a[i] * i;
    }
    for(int i=n;i>=1;i--)
    {
        suf[i] = suf[i+1] + a[i] * (n - i + 1);
    }
    built(1,1,n);
    int q;
    cin>>q;
    while(q--)
    {
        int ty;
        cin>>ty;
        if(ty == 2){
            int l,r,m;
            cin>>l>>r>>m;
            if((r - l + 1) >= m*2){
                ///первый случай когда m слишком маленький, в таком случае нужно посчитать 1 + 2 + ... m - 1
                long long res = get(1,1,n,l + (m - 1) , r - (m - 1))*m;
                cerr<<"res = "<<res<<endl;
                ///вот тут мы посчитали середину

                ///теперь нужно добавить 1 + 2 + ... m - 1
                ///давай реализуем функцию prf(l, r) которая будет уметь считать 1 + 2...,
                ///а так же такую же функцию syf которая будет уметь считать 2 + 1 ...
                ///так как очень много одинаковых блоков кода где может быть ошибка


                res += prf(l, l + m - 2);
                res += syf(r - m + 2, r);
                cerr<<"1    ";
                cout << res << endl;
            }
            else{
                int cur_m = r - l + 2 - m;
                ///cur_m

                long long res = 0;
                res += prf(l, l + cur_m - 1);
                res += syf(r - cur_m + 1, r);
                res += get(1, 1, n, l + cur_m, r - cur_m) * cur_m;
                cerr<<"3    ";
                cout << res << endl;
            }
        }
        else{
            for(int i=0;i<k;i++){
                int x;
                cin>>x;
            }
        }
    }
}


/*
8 5
1 1 1 1 1 1 1 1
1
2 1 8 5
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...