Submission #838489

#TimeUsernameProblemLanguageResultExecution timeMemory
838489Elvin_FritlAddk (eJOI21_addk)C++17
64 / 100
366 ms12440 KiB
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5; #define int long long int n,k; int a[N]; long long tree[N*3],trep[N*3],tres[N*3]; void built(int v,int l,int r) { if(l > r) { return; } if(l == r) { tree[v] = a[l]; trep[v] = a[l]*l; tres[v] = a[l]*(n - l + 1); ///cerr << "l == " << l << " " << trep[v] << " " << tres[v] << endl; 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]; trep[v] = trep[v*2] + trep[v*2 + 1]; tres[v] = tres[v*2] + tres[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 getp(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 trep[v]; } int mid=(l+r)>>1; return getp(v*2 , l , mid , ml , mr) + getp(v*2 + 1,mid + 1,r,ml,mr); } long long gets(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 tres[v]; } int mid=(l+r)>>1; return gets(v*2 , l , mid , ml , mr) + gets(v*2 + 1,mid + 1,r,ml,mr); } void update(int v,int l,int r,int ind,int val) { if(l > r) { return; } if(l == r) { a[l] = val; tree[v] = a[l]; trep[v] = a[l]*l; tres[v] = a[l]*(n - l + 1); ///cerr << "l == " << ind << " " << trep[v] << " " << tres[v] << endl; return; } int mid=(l+r)>>1; if(ind <= mid){ update(v*2,l,mid,ind,val); } else{ update(v*2 + 1,mid+1,r,ind,val); } tree[v] = tree[v*2] + tree[v*2 + 1]; trep[v] = trep[v*2] + trep[v*2 + 1]; tres[v] = tres[v*2] + tres[v*2 + 1]; } long long prf(int l, int r){ ///мы хотим посчитать 1 + 2 + 3... на подотрезке, возьмем преффиксную сумму на этом подотрезке long long sum = getp(1,1,n,l,r); ///cerr <<"pre "<< sum<<endl; ///assert(sum == sum2); ///теперь отнимем сумму на подотрезке sum -= (l - 1) * (get(1, 1, n, l, r)); return sum; } long long syf(int l, int r){ ///полностью зеркальная функция long long sum = gets(1,1,n,l,r); ///cerr << "suf "<< sum <<endl; ///assert(sum == sum2); sum -= (n - r) * get(1, 1, n, l, r); return sum; } int32_t main(){ cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a[i]; } built(1,1,n); int q; cin>>q; while(q--) { int ty; cin>>ty; if(ty == 2){ int l,r; long long m; cin>>l>>r>>m; assert(r >= l); if((r - l + 1) >= m*2){ ///первый случай когда m слишком маленький, в таком случае нужно посчитать 1 + 2 + ... m - 1 assert(l + m - 1 <= r - m + 1); long long res = get(1,1,n,l + (m - 1) , r - (m - 1))*m; ///вот тут мы посчитали середину ///теперь нужно добавить 1 + 2 + ... m - 1 ///давай реализуем функцию prf(l, r) которая будет уметь считать 1 + 2..., ///а так же такую же функцию syf которая будет уметь считать 2 + 1 ... ///так как очень много одинаковых блоков кода где может быть ошибка assert(l + m - 2 <= r - m + 2); res += prf(l, l + m - 2); res += syf(r - m + 2, r); cout << res << endl; } else{ int cur_m = r - l + 2 - m; assert(cur_m <= m && cur_m > 0); ///cur_m long long res = 0; ///assert(l + cur_m == r - cur_m); res += prf(l, l + cur_m - 1); res += syf(r - cur_m + 1, r); ///cerr << r - cur_m << " " << l + cur_m << endl; res += get(1, 1, n, l + cur_m, r - cur_m) * cur_m; ///cerr<<"3 "; cout << res << endl; } } else{ vector<int>ind; for(int i=0;i<k;i++){ int x; cin>>x; ind.push_back(x); } int fi = a[ind[0]]; for(int i=1;i<k;i++){ update(1,1,n,ind[i-1],a[ind[i]]); } update(1,1,n,ind[k-1],fi); } } } /* 2 3 4 5 6 7 9 5 1 6 3 4 1 2 3 3 2 1 9 + 10 + 3 + 18 + 6 + 4 = 20 + 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...