// Problem: E. Space Harbour
// Contest: Codeforces - Codeforces Round 921 (Div. 2)
// URL: https://codeforces.com/contest/1925/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using VI = vector<int>;
using PII = pair<ll,ll>;
using VVI = vector<vector<int>>;
const ll mod = 998244353;
const ll INF = 1e18;
const int N = 3e5 + 10;
int n,m,q;
struct segtree{
ll sum[N << 2];
void pushup(int p){
sum[p] = sum[p << 1] + sum[p << 1 | 1];
}
void change(int p , int left , int right , int x , ll val){
if(left == right){
sum[p] = val;
return ;
}
int mid = (left + right) >> 1;
if(x <= mid) change(p << 1 , left , mid , x , val);
else change(p << 1 | 1 , mid + 1 , right , x , val);
pushup(p);
}
ll query(int p ,int left , int right , int ql , int qr){
if(ql > qr) return 0;
if(ql <= left && right <= qr){
return sum[p];
}
int mid = (left + right) >> 1;
ll res = 0;
if(ql <= mid) res += query(p << 1 , left , mid , ql , qr);
if(qr > mid) res += query(p << 1 | 1 , mid + 1 , right , ql , qr);
return res;
}
}t;
ll calc(ll p , ll u){
if(u <= p) return 0;
return (u - p) * (u - p + 1) / 2;
}
PII p[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>q;
VI x(n + 2 , 0);
VI v(n + 2 , 0);
//vector<PII> p(n + 2 , 0);
map<int,int> mp;
for(int i = 1 ; i <= m ; i++)cin>>x[i];
for(int i = 1 ; i <= m ; i++){
cin>>v[i];
p[i] = {x[i] , v[i]};
}
sort(p + 1 , p + 1 + m);
for(int i = 1 ; i <= m ; i++){
x[i] = p[i].first , v[i] = p[i].second;
mp.insert({x[i] , v[i]});
//cout<<x[i]<<" "<<v[i]<<"\n";
//cout<<v[i - 1] * calc(x[i - 1] + 1 , x[i])<<"\n";
t.change(1 , 1 , n , x[i] , v[i - 1] * calc(x[i - 1] + 1 , x[i]));
}
/* cout<<endl;
cout<<t.query(1 , 1 , n , 1 , n)<<'\n';
*/
while(q--){
int op;
cin>>op;
if(op == 1){
int xx,vv;
cin>>xx>>vv;
auto it = mp.upper_bound(xx);
PII nex = *it;
PII pre = *(--it);
//if(nex.first == n) pre
//cout<<pre.first<<" "<<pre.second<<"\n";
//cout<<pre.second * calc(pre.first + 1 , xx)<<"\n";
t.change(1 , 1 , n , xx , pre.second * calc(pre.first + 1 , xx));
t.change(1 , 1 , n , nex.first , vv * calc(xx + 1 , nex.first));
mp.insert({xx , vv});
}else{
int l,r;
cin>>l>>r;
// l r
// ql qr
ll res = 0;
int ql,qr;
auto it = mp.lower_bound(l);
PII nex = *it;
PII pre = *(--it);
//cout<<pre.second * calc(l , nex.first)<<"\n";
res += pre.second * calc(l , nex.first);
ql = nex.first + 1;
it = mp.lower_bound(r);
nex = *it;
pre = *(--it);
qr = nex.first;
res -= pre.second * calc(r + 1 , nex.first);
/* cout << pre.second * calc(r + 1 , nex.first)<<'\n';
cout<<ql<<" "<<qr<<"\n";*/
/* cout<<t.query(1 , 1 , n , ql , qr)<<'\n';*/
res += t.query(1 , 1 , n , ql , qr);
cout<<res<<"\n";
}
///cout<<endl;
}
}
//5 4 3 2 1
//5 4 3 2 1
本质上不是一个很困难的题目,只要是我调代码能力太拉了
通过map实现查询的大于和小于的点,迭代器要先--
采用类似于分块的做法处理 2 查询 ,中间的利用线段树直接计算,两边少算的部分利用等差数列公式计算。但是注意在线段树上做查询的时候左区间要 +1 , 因为左区间上的val并不代表这个点的值,而是一段区间的值放在了这个港口上,这个点本上的值是0,要选的是从港口 + 1开始
右边多算的是从[r + 1 , nex]
左边少算的是从[l , nex]