This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |