Problem:
Problem F: Bus
Problem
円環状に $1$ から $N$ までの番号がつけられた $N$ 個のバス停が右回りに並んでいる。
  隣接するバス停どうしは道で結ばれている。
  各 $i \ (1 \le i \le N)$ について、バス停 $i$ とバス停 $i+1$ の間を直接結ぶ道の長さは $d_i$ メートルである。
  ただし、バス停 $N+1$ はバス停 $1$ のことを表す。
$M$ 台のバスがある。
  $j \ (1 \le j \le M)$ 番目のバスは $c_j='R'$ のとき右回り、$c_j='L'$ のとき左回りに走行する。
  また、時刻 $0$ にバス停 $b_j$ を出発し、$1$ メートル進むのに $t_j$ 秒かかる。
この問題において、
バスは永遠に走り続ける
バスの乗り降りには時間がかからない
バス停では、あるバスがそのバス停を通過する瞬間、そのバスに乗り降りできる
バス停以外でバスに乗り降りすることはできない
何台のバスに乗ってもよい
とする。
以下のクエリを合計 $Q$ 回処理せよ。
時刻 $0$ にバス停 $x_k$ を出発し、バス停 $y_k$ までバスのみを利用して移動するときの、所要時間の最小値を求めよ。
Input
入力は以下の形式で与えられる。
$N$ $M$ $Q$
$d_1$ $\ldots$ $d_N$
$c_1$ $b_1$ $t_1$
$\vdots$
$c_M$ $b_M$ $t_M$
$x_1$ $y_1$
$\vdots$
$x_Q$ $y_Q$
1行目にバス停の数 $N$、バスの数 $M$、クエリの数 $Q$ が空白区切りで与えられる。
2行目に隣接するバス停を繋ぐ道の情報が空白区切りで与えられる。
3行目から続く $M$ 行にバスの情報が空白区切りで与えられる。
続く $Q$ 行にクエリの情報が空白区切りで与えられる。
Constraints
入力は以下の条件を満たす。
$3 \leq N \leq 10^5 $
$1 \leq M \leq 10^5 $
$1 \leq Q \leq 10^5 $
$ 1 \leq d_i \leq 10^2 \  (1 \leq i \leq N) $
$ c_j = 'R' \ or \ 'L' \ (1 \leq j \leq M) $
$ 1 \leq b_j \leq N \ (1 \leq j \leq M) $
$ 1 \leq t_j \leq 10^5 \ (1 \leq j \leq M) $
$ 1 \leq x_k, y_k \leq N \ (1 \leq k \leq Q) $
$ x_k \neq y_k \ (1 \leq k \leq Q) $
入力で与えられる数はすべて整数
Output
出力は $Q$ 行からなる。
各クエリに対し、所要時間の最小値を出力せよ。
$k$ 行目には $k$ 番目のクエリに対する答えを出力せよ。
Sample Input 1
3 1 6
1 2 3
R 1 1
1 2
1 3
2 1
2 3
3 1
3 2
Sample Output 1
1
3
6
3
6
7
$1$ つ目のクエリでは、時刻 $0$ にバス停 $1$ からバス $1$ に乗り、時刻 $1$ にバス停 $2$ で降りるのが最適である。
Sample Input 2
4 6 7
45 72 81 47
R 1 47202
L 1 2156
L 2 95728
R 1 30739
L 3 39679
L 4 86568
3 2
3 4
1 2
2 4
4 3
1 4
2 1
Sample Output 2
431200
629552
431200
629552
275968
101332
528220

Submitted solutions:

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3069

#include<bits/stdc++.h>
using namespace std;

#define call_from_test

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
enum Objective{
  MAXIMIZE = +1,
  MINIMIZE = -1,
};

template<typename T>
struct Line {
  mutable T k,m,p;
  bool operator<(const Line&o)const{return k<o.k;}
  bool operator<(T x)const{return p<x;}
};

template<typename T> T lc_inf(){return numeric_limits<T>::max();}
template<> double lc_inf<double>(){return 1/.0;}

template<typename T> T lc_div(T a,T b){return a/b-((a^b)<0 and a%b);}
template<> double lc_div(double a,double b){return a/b;};

template<typename T, Objective objective>
struct LineContainer : multiset<Line<T>, less<>>{
  using super = multiset<Line<T>, less<>>;
  using super::begin,super::end,super::insert,super::erase;
  using super::empty,super::lower_bound;
  const T inf = lc_inf<T>();
  bool insect(typename super::iterator x,typename super::iterator y){
    if(y==end()) return x->p=inf,false;
    if(x->k==y->k) x->p=(x->m>y->m?inf:-inf);
    else x->p=lc_div(y->m-x->m,x->k-y->k);
    return x->p>=y->p;
  }
  void add(T k,T m){
    auto z=insert({k*objective,m*objective,0}),y=z++,x=y;
    while(insect(y,z)) z=erase(z);
    if(x!=begin() and insect(--x,y)) insect(x,y=erase(y));
    while((y=x)!=begin() and (--x)->p>=y->p) insect(x,erase(y));
  }
  T query(T x){
    assert(!empty());
    auto l=*lower_bound(x);
    return (l.k*x+l.m)*objective;
  }
};
template<typename T>
using MinLineContainer = LineContainer<T, Objective::MINIMIZE>;
template<typename T>
using MaxLineContainer = LineContainer<T, Objective::MAXIMIZE>;
//END CUT HERE

#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  using ll = long long;
  int n,m,q;
  cin>>n>>m>>q;

  vector<ll> ds(n);
  for(int i=0;i<n;i++) cin>>ds[i];
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));

  vector<ll> sm(n*3+1,0);
  for(int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<int> bs(m),ts(m);
  for(int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<ll> > G(n*3);
  vector<ll> xs(q),ys(q);
  for(int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
    G[xs[i]].emplace_back(i);
  }

  const ll INF = 1e18;
  vector<ll> R(n*3,INF),L(n*3,INF);
  int exR=0,exL=0;
  for(int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<ll> ans(q,INF);

  // use R
  if(exR){
    MinLineContainer<ll> cht;
    for(int x=0;x<n*2;x++){
      if(R[x]!=INF) cht.add(R[x],-R[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  // use L
  if(exL){
    MinLineContainer<ll> cht;
    for(int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) cht.add(-L[x],L[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  for(int i=0;i<q;i++) cout<<ans[i]<<'\n';
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 31152
final_rank: 8

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3069

#include<bits/stdc++.h>
using namespace std;

#define call_from_test

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
enum Objective{
  MAXIMIZE = +1,
  MINIMIZE = -1,
};

template<typename T>
struct Line {
  mutable T k,m,p;
  bool operator<(const Line&o)const{return k<o.k;}
  bool operator<(T x)const{return p<x;}
};

template<typename T> T lc_inf(){return numeric_limits<T>::max();}
template<> double lc_inf<double>(){return 1/.0;}

template<typename T> T lc_div(T a,T b){return a/b-((a^b)<0 and a%b);}
template<> double lc_div(double a,double b){return a/b;};

template<typename T, Objective objective>
struct LineContainer : multiset<Line<T>, less<>>{
  using super = multiset<Line<T>, less<>>;
  using super::begin, super::end, super::insert, super::erase;
  using super::empty, super::lower_bound;
  const T inf = lc_inf<T>();
  bool insect(typename super::iterator x,typename super::iterator y){
    if(y==end()) return x->p=inf,false;
    if(x->k==y->k) x->p=(x->m>y->m?inf:-inf);
    else x->p=lc_div(y->m-x->m,x->k-y->k);
    return x->p>=y->p;
  }
  void add(T k,T m){
    auto z=insert({k*objective,m*objective,0}),y=z++,x=y;
    while(insect(y,z)) z=erase(z);
    if(x!=begin() and insect(--x,y)) insect(x,y=erase(y));
    while((y=x)!=begin() and (--x)->p>=y->p) insect(x,erase(y));
  }
  T query(T x){
    assert(!empty());
    auto l=*lower_bound(x);
    return (l.k*x+l.m)*objective;
  }
};
template<typename T>
using MinLineContainer = LineContainer<T, Objective::MINIMIZE>;
template<typename T>
using MaxLineContainer = LineContainer<T, Objective::MAXIMIZE>;

//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  using ll = long long;
  int n,m,q;
  cin>>n>>m>>q;

  vector<ll> ds(n);
  for(int i=0;i<n;i++) cin>>ds[i];
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));

  vector<ll> sm(n*3+1,0);
  for(int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<int> bs(m),ts(m);
  for(int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<ll> > G(n*3);
  vector<ll> xs(q),ys(q);
  for(int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
    G[xs[i]].emplace_back(i);
  }

  const ll INF = 1e18;
  vector<ll> R(n*3,INF),L(n*3,INF);
  int exR=0,exL=0;
  for(int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<ll> ans(q,INF);

  // use R
  if(exR){
    MinLineContainer<ll> cht;
    for(int x=0;x<n*2;x++){
      if(R[x]!=INF) cht.add(R[x],-R[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  // use L
  if(exL){
    MinLineContainer<ll> cht;
    for(int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) cht.add(-L[x],L[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  for(int i=0;i<q;i++) cout<<ans[i]<<'\n';
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 30648
final_rank: 5

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3069

#include<bits/stdc++.h>
using namespace std;

#define call_from_test

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
enum Objective{
  MINIMIZE = +1,
  MAXIMIZE = -1,
};

template<typename T>
struct Line {
  mutable T k,m,p;
  bool operator<(const Line&o)const{return k<o.k;}
  bool operator<(T x)const{return p<x;}
};

template<typename T> T lc_inf(){return numeric_limits<T>::max();}
template<> double lc_inf<double>(){return 1/.0;}

template<typename T> T lc_div(T a,T b){return a/b-((a^b)<0 and a%b);}
template<> double lc_div(double a,double b){return a/b;};

template<typename T, Objective objective = Objective::MAXIMIZE>
struct LineContainer : multiset<Line<T>, less<>>{
  using super = multiset<Line<T>, less<>>;
  using super::begin, super::end, super::insert, super::erase;
  using super::empty, super::lower_bound;
  const T inf = lc_inf<T>();
  bool insect(typename super::iterator x,typename super::iterator y){
    if(y==end()) return x->p=inf,false;
    if(x->k==y->k) x->p=(x->m>y->m?inf:-inf);
    else x->p=lc_div(y->m-x->m,x->k-y->k);
    return x->p>=y->p;
  }
  void add(T k,T m){
    auto z=insert({k*objective,m*objective,0}),y=z++,x=y;
    while(insect(y,z)) z=erase(z);
    if(x!=begin() and insect(--x,y)) insect(x,y=erase(y));
    while((y=x)!=begin() and (--x)->p>=y->p) insect(x,erase(y));
  }
  T query(T x){
    assert(!empty());
    auto l=*lower_bound(x);
    return (l.k*x+l.m)*objective;
  }
};

//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  using ll = long long;
  int n,m,q;
  cin>>n>>m>>q;

  vector<ll> ds(n);
  for(int i=0;i<n;i++) cin>>ds[i];
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));

  vector<ll> sm(n*3+1,0);
  for(int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<int> bs(m),ts(m);
  for(int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<ll> > G(n*3);
  vector<ll> xs(q),ys(q);
  for(int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
    G[xs[i]].emplace_back(i);
  }

  const ll INF = 1e18;
  vector<ll> R(n*3,INF),L(n*3,INF);
  int exR=0,exL=0;
  for(int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<ll> ans(q,INF);

  // use R
  if(exR){
    LineContainer<ll> cht;
    for(int x=0;x<n*2;x++){
      if(R[x]!=INF) cht.add(R[x],-R[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  // use L
  if(exL){
    LineContainer<ll> cht;
    for(int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) cht.add(-L[x],L[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  for(int i=0;i<q;i++) cout<<ans[i]<<'\n';
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 30680
final_rank: 6

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3069

#include<bits/stdc++.h>
using namespace std;

#define call_from_test

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE

template<typename T>
struct Line {
  mutable T k,m,p;
  bool operator<(const Line&o)const{return k<o.k;}
  bool operator<(T x)const{return p<x;}
};

template<typename T> T lc_inf(){return numeric_limits<T>::max();}
template<> double lc_inf<double>(){return 1/.0;}

template<typename T> T lc_div(T a,T b){return a/b-((a^b)<0 and a%b);}
template<> double lc_div(double a,double b){return a/b;};

template<typename T>
struct LineContainer : multiset<Line<T>, less<>>{
  using super = multiset<Line<T>, less<>>;
  using super::begin, super::end, super::insert, super::erase;
  using super::empty, super::lower_bound;

  const T inf = lc_inf<T>();
  bool insect(typename super::iterator x,typename super::iterator y){
    if(y==end()) return x->p=inf,false;
    if(x->k==y->k) x->p=(x->m>y->m?inf:-inf);
    else x->p=lc_div(y->m-x->m,x->k-y->k);
    return x->p>=y->p;
  }
  void add(T k,T m){
    auto z=insert({k,m,0}),y=z++,x=y;
    while(insect(y,z)) z=erase(z);
    if(x!=begin() and insect(--x,y)) insect(x,y=erase(y));
    while((y=x)!=begin() and (--x)->p>=y->p) insect(x,erase(y));
  }
  T query(T x){
    assert(!empty());
    auto l=*lower_bound(x);
    return l.k*x+l.m;
  }
};

//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  using ll = long long;
  int n,m,q;
  cin>>n>>m>>q;

  vector<ll> ds(n);
  for(int i=0;i<n;i++) cin>>ds[i];
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));

  vector<ll> sm(n*3+1,0);
  for(int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<int> bs(m),ts(m);
  for(int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<ll> > G(n*3);
  vector<ll> xs(q),ys(q);
  for(int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
    G[xs[i]].emplace_back(i);
  }

  const ll INF = 1e18;
  vector<ll> R(n*3,INF),L(n*3,INF);
  int exR=0,exL=0;
  for(int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<ll> ans(q,INF);

  // use R
  if(exR){
    LineContainer<ll> cht;
    auto add=[&](ll k,ll m){cht.add(-k,-m);};
    auto query=[&](ll x){return -cht.query(x);};
    for(int x=0;x<n*2;x++){
      if(R[x]!=INF) add(R[x],-R[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],query(sm[y]));
      }
    }
  }

  // use L
  if(exL){
    LineContainer<ll> cht;
    auto add=[&](ll k,ll m){cht.add(-k,-m);};
    auto query=[&](ll x){return -cht.query(x);};
    for(int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) add(-L[x],L[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],query(sm[y]));
      }
    }
  }

  for(int i=0;i<q;i++) cout<<ans[i]<<'\n';
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 30896
final_rank: 7

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3069

#include<bits/stdc++.h>
using namespace std;

#define call_from_test

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE

template<typename T>
struct Line {
  mutable T k,m,p;
  bool operator<(const Line&o)const{return k<o.k;}
  bool operator<(T x)const{return p<x;}
};

template<typename T>
struct LineContainer : multiset<Line<T>, less<>>{
  using super = multiset<Line<T>, less<>>;
  using super::begin, super::end, super::insert, super::erase;
  using super::empty, super::lower_bound;

  template<typename X>
  using is_float = enable_if< is_floating_point<X>::value>;
  template<typename X>
  using is_int   = enable_if<!is_floating_point<X>::value>;

  template<typename X=T,typename is_float<X>::type * = nullptr>
  static constexpr T get_inf(){return 1/.0;}
  template<typename X=T,typename is_int<X>::type * = nullptr>
  static constexpr T get_inf(){return numeric_limits<T>::max();}

  const T inf = get_inf();

  template<typename X=T,typename is_float<X>::type * = nullptr>
  T div(T a,T b){return a/b;}
  template<typename X=T,typename is_int<X>::type * = nullptr>
  T div(T a,T b){return a/b-((a^b)<0 and a%b);}

  bool insect(typename super::iterator x,typename super::iterator y){
    if(y==end()) return x->p=inf,false;
    if(x->k==y->k) x->p=(x->m>y->m?inf:-inf);
    else x->p=div(y->m-x->m,x->k-y->k);
    return x->p>=y->p;
  }
  void add(T k,T m){
    auto z=insert({k,m,0}),y=z++,x=y;
    while(insect(y,z)) z=erase(z);
    if(x!=begin() and insect(--x,y)) insect(x,y=erase(y));
    while((y=x)!=begin() and (--x)->p>=y->p) insect(x,erase(y));
  }
  T query(T x){
    assert(!empty());
    auto l=*lower_bound(x);
    return l.k*x+l.m;
  }
};

//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  using ll = long long;
  int n,m,q;
  cin>>n>>m>>q;

  vector<ll> ds(n);
  for(int i=0;i<n;i++) cin>>ds[i];
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));
  for(int i=0;i<n;i++) ds.emplace_back(int(ds[i]));

  vector<ll> sm(n*3+1,0);
  for(int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<int> bs(m),ts(m);
  for(int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<ll> > G(n*3);
  vector<ll> xs(q),ys(q);
  for(int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
    G[xs[i]].emplace_back(i);
  }

  const ll INF = 1e18;
  vector<ll> R(n*3,INF),L(n*3,INF);
  int exR=0,exL=0;
  for(int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<ll> ans(q,INF);

  // use R
  if(exR){
    LineContainer<ll> cht;
    auto add=[&](ll k,ll m){cht.add(-k,-m);};
    auto query=[&](ll x){return -cht.query(x);};
    for(int x=0;x<n*2;x++){
      if(R[x]!=INF) add(R[x],-R[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],query(sm[y]));
      }
    }
  }

  // use L
  if(exL){
    LineContainer<ll> cht;
    auto add=[&](ll k,ll m){cht.add(-k,-m);};
    auto query=[&](ll x){return -cht.query(x);};
    for(int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) add(-L[x],L[x]*sm[x]);
      for(int i:G[x]){
        int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],query(sm[y]));
      }
    }
  }

  for(int i=0;i<q;i++) cout<<ans[i]<<'\n';
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 30732
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>

#define llint long long
#define inf 1e18

using namespace std;

typedef pair<llint, llint> P;

struct LiChaoTree{
	int size;
	vector<P> seg;
	vector<llint> x;
	
	LiChaoTree(){}
	LiChaoTree(int size){
		this->size = size;
		seg.resize(1<<(size+1));
		x.resize(1<<size);
	}
	
	void init()
	{
		for(int i = 0; i < (1<<(size+1)); i++) seg[i] = make_pair(0, inf);
		for(int i = 0; i < (1<<size); i++) x[i] = i;
	}
	llint calc(P f, llint x)
	{
		return f.first * x + f.second;
	}
	llint query(int i) //x[i]における最小値を取得
	{
		llint X = x[i], ret = inf;
		i += (1 << size);
		while(i >= 1){
			ret = min(ret, calc(seg[i], X));
			i /= 2;
		}
		return ret;
	}
	void add(int k, int l, int r, P f)
	{
		int m = (l+r)/2;
		if(calc(f, x[m]) < calc(seg[k], x[m])) swap(seg[k], f);
		bool L = (calc(f, x[l]) < calc(seg[k], x[l])), R = (calc(f, x[r]) < calc(seg[k], x[r]));
		if(L == R) return;
		if(L) add(k*2, l, m, f);
		if(R) add(k*2+1, m+1, r, f);
	}
	void addSegment(int a, int b, int k, int l, int r, P f)
	{
		if(b < l || r < a) return;
		if(a <= l && r <= b){
			add(k, l, r, f);
			return;
		}
		addSegment(a, b, k*2, l, (l+r)/2, f);
		addSegment(a, b, k*2+1, (l+r)/2+1, r, f);
	}
	void addSegment(int a, int b, llint p, llint q) //区間[x[a], x[b]]に線分px+qを追加
	{
		addSegment(a, b, 1, 0, (1<<size)-1, make_pair(p, q));
	}
	void addLine(llint p, llint q) //直線px+qを追加
	{
		return addSegment(0, (1<<size)-1, p, q);
	}
};

llint n, m, Q, L;
llint p[100005], np[100005];
char c[100005];
llint b[100005], t[100005];
llint x[100005], y[100005];
llint ans[100005];
vector<llint> qvec[100005], bvec[100005];
vector<llint> comp;
LiChaoTree lct(17);

llint dist(llint s, llint t)
{
	if(t >= s) return t-s;
	else return t-s+L;
}

void solve()
{
	for(int i = 0; i < n; i++) qvec[i].clear();
	for(int i = 1; i <= Q; i++) qvec[x[i]].push_back(i);
	
	for(int i = 0; i < n; i++) bvec[i].clear();
	for(int i = 1; i <= m; i++){
		if(c[i] == 'R') bvec[b[i]].push_back(i);
	}
	
	comp.clear();
	for(int i = 1; i <= Q; i++) comp.push_back(p[x[i]]+dist(p[x[i]], p[y[i]]));
	sort(comp.begin(), comp.end());
	comp.erase(unique(comp.begin(), comp.end()), comp.end());
	int N = comp.size();
	
	lct.init();
	for(int i = 0; i < (1<<17); i++){
		if(i < N) lct.x[i] = comp[i];
		else lct.x[i] = 1e9;
	}
	
	for(int i = 1; i <= m; i++){
		if(c[i] == 'R') lct.addLine(t[i], -(p[b[i]]-L)*t[i]);
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < bvec[i].size(); j++){
			int bid = bvec[i][j];
			lct.addLine(t[bid], -(p[b[bid]])*t[bid]);
		}
		for(int j = 0; j < qvec[i].size(); j++){
			int qid = qvec[i][j];
			llint id = lower_bound(comp.begin(), comp.end(), p[x[qid]] + dist(p[x[qid]], p[y[qid]])) - comp.begin();
			ans[qid] = min(ans[qid], lct.query(id));
		}
	}
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> m >> Q;
	llint d;
	for(int i = 0; i < n; i++){
		cin >> d;
		p[i] = L;
		L += d;
	}
	for(int i = 1; i <= m; i++) cin >> c[i] >> b[i] >> t[i], b[i]--;
	for(int i = 1; i <= Q; i++) cin >> x[i] >> y[i], x[i]--, y[i]--;
	for(int i = 1; i <= Q; i++) ans[i] = inf;
	
	solve();
	
	for(int i = 1; i < n; i++) np[i] = L-p[n-i];
	for(int i = 0; i < n; i++) p[i] = np[i];
	for(int i = 1; i <= m; i++){
		if(c[i] == 'L') c[i] = 'R';
		else c[i] = 'L';
		if(b[i] > 0) b[i] = n-b[i];
	}
	for(int i = 1; i <= Q; i++){
		if(x[i] > 0) x[i] = n-x[i];
		if(y[i] > 0) y[i] = n-y[i];
	}
	
	solve();
	
	for(int i = 1; i <= Q; i++) cout << ans[i] << "\n";
	flush(cout);
	
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 24728
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;


template<typename T,bool isMin>
struct NonmonotonicConvexHullTrick {
  using number = double;
  static constexpr number INF = numeric_limits<T>::max();
  struct Line {
    T m,b,val;
    number x;
    bool q;
    Line(T m=0,T b=0):m(m),b(b),val(0),x(-INF),q(false){}

    T eval(T x) const{return m*x+b;}
    bool parallel(const Line &l) const{return m==l.m;}
    number intersect(const Line &l) const{
      return parallel(l)?number(INF):number(l.b-b)/number(m-l.m);
    }
    bool operator<(const Line &l) const{
      if(l.q) return x<l.val;
      return m<l.m;
    }
  };

  set<Line> hull;
  using iter = typename set<Line>::iterator;

  bool cPrev(iter it){return it!=hull.begin();}
  bool cNext(iter it){return it!=hull.end()&&next(it)!=hull.end();}

  bool bad(const Line &l1,const Line &l2,const Line &l3){
    return l1.intersect(l3) <= l1.intersect(l2);
  }
  bool bad(iter it){
    return cPrev(it)&&cNext(it)&&bad(*prev(it),*it,*next(it));
  }

  iter update(iter it){
    if(!cPrev(it)) return it;
    number x=it->intersect(*prev(it));
    Line tmp(*it);
    tmp.x=x;
    it=hull.erase(it);
    return hull.insert(it,tmp);
  }

  void addLine(T m,T b){
    if(isMin) m=-m,b=-b;
    Line l(m,b);
    iter it=hull.lower_bound(l);
    if(it!=hull.end()&&l.parallel(*it)){
      if(it->b<b) it=hull.erase(it);
      else return;
    }
    it=hull.insert(it,l);
    if(bad(it)){
      hull.erase(it);
      return;
    }
    while(cPrev(it)&&bad(prev(it))) hull.erase(prev(it));
    while(cNext(it)&&bad(next(it))) hull.erase(next(it));

    it=update(it);
    if(cPrev(it)) update(prev(it));
    if(cNext(it)) update(next(it));
  }

  bool empty() const{
    return hull.empty();
  }

  T query(T x){
    assert(!empty());
    Line q;
    q.val=x;q.q=1;
    iter it=--hull.lower_bound(q);
    if(isMin) return -(it->eval(x));
    return it->eval(x);
  }
} ;

//INSERT ABOVE HERE
signed main(){
  Int n,m,q;
  cin>>n>>m>>q;

  vector<Int> ds(n);
  for(Int i=0;i<n;i++) cin>>ds[i];
  for(Int i=0;i<n;i++) ds.emplace_back(Int(ds[i]));
  for(Int i=0;i<n;i++) ds.emplace_back(Int(ds[i]));

  vector<Int> sm(n*3+1,0);
  for(Int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<Int> bs(m),ts(m);
  for(Int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<Int> > G(n*3);
  vector<Int> xs(q),ys(q);
  for(Int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
     G[xs[i]].emplace_back(i);
  }

  const Int INF = 1e18;
  vector<Int> R(n*3,INF),L(n*3,INF);
  Int exR=0,exL=0;
  for(Int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<Int> ans(q,INF);
  // use R
  if(exR){
    NonmonotonicConvexHullTrick<Int, true> cht;
    for(Int x=0;x<n*2;x++){
      if(R[x]!=INF) cht.addLine(R[x],-R[x]*sm[x]);
      for(Int i:G[x]){
        Int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }
  // use L
  if(exL){
    NonmonotonicConvexHullTrick<Int, true> cht;
    for(Int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) cht.addLine(-L[x],L[x]*sm[x]);
      for(Int i:G[x]){
        Int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  for(Int i=0;i<q;i++) cout<<ans[i]<<"\n";
  cout<<flush;
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 32708
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define INF_LL (int64)1e18
#define INF (int32)1e9
#define REP(i, n) for(int64 i = 0;i < (n);i++)
#define FOR(i, a, b) for(int64 i = (a);i < (b);i++)
#define all(x) x.begin(),x.end()
#define fs first
#define sc second

using int32 = int_fast32_t;
using uint32 = uint_fast32_t;
using int64 = int_fast64_t;
using uint64 = uint_fast64_t;
using PII = pair<int32, int32>;
using PLL = pair<int64, int64>;

const double eps = 1e-10;

template<typename A, typename B>inline void chmin(A &a, B b){if(a > b) a = b;}
template<typename A, typename B>inline void chmax(A &a, B b){if(a < b) a = b;}

template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value!=0>::type
fill_v(U &u,const V... v){u=U(v...);}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value==0>::type
fill_v(U &u,const V... v){
  for(auto &e:u) fill_v<T>(e,v...);
}
template<typename T = ::std::int64_t, class Compare = ::std::less<T>>
class LiChaoTree{
private:
    static Compare comp;
    using size_type = ::std::size_t;

    struct Line{
        T a, b;
        bool used;
        Line() : a(0), b(0), used(false) {}
        Line(const T &a_, const T &b_) : a(a_), b(b_), used(true) {}
        T operator()(const T &x) { return a*x+b; }
    };

    size_type n, cnt;
    ::std::vector<Line> node;
    ::std::vector<T> pos;

    void add(size_type l, size_type r, const Line &line){
        cnt++;
        size_type l0 = l, r0 = r;
        size_type sz = 1;
        for (l += n, r += n; l < r; l >>= 1, r >>= 1, sz <<= 1) {
            if (l & 1) add(l, l0, l0+sz, line), l0 += sz, l++;
            if (r & 1) --r, r0 -= sz, add(r, r0, r0+sz, line);
        }
    }

    void add(size_type k, size_type l, size_type r, Line line){
        if (!node[k].used) {
            node[k] = line;
            return;
        }
        T ly = line(pos[l]), ry = line(pos[r-1]);
        T nly = node[k](pos[l]), nry = node[k](pos[r-1]);
        if (comp(nly, ly) && comp(nry, ry)) return;
        if (comp(ly, nly) && comp(ry, nry)) {
            node[k] = line;
            return;
        }
        if (r - l == 1) return;
        size_type m = (l + r) >> 1;
        if (comp(nly, ly)) swap(node[k], line);
        if (comp(line(pos[m]), node[k](pos[m]))) {
            swap(node[k], line);
            add((k << 1) | 1, m, r, line);
        } else {
            add(k << 1, l, m, line);
        }
    }
public:
    LiChaoTree(){}
    LiChaoTree(const ::std::vector<T> &v) : pos(v), cnt(0) {
        n = 1;
        while (n < pos.size()) n <<= 1;
        sort(pos.begin(), pos.end());
        pos.erase(unique(pos.begin(), pos.end()), pos.end());
        pos.resize(n, pos.back());
        node.resize(n << 1);
    }

    void add(T a, T b){
        add(0, n, Line(a, b));
    }

    void add(T a, T b, T lx, T rx){
        size_type l = lower_bound(pos.begin(), pos.end(), lx) - pos.begin();
        size_type r = lower_bound(pos.begin(), pos.end(), rx) - pos.begin();
        add(l, r, Line(a, b));
    }

    ::std::pair<bool, T> query(T x) {
        Line l = get(x);
        return ::std::make_pair(l.used, l(x));
    }

    Line get(T x){
        size_type i = lower_bound(pos.begin(), pos.end(), x) - pos.begin() + n;
        size_type res = -1;
        for(; i > 0; i >>= 1){
            if (node[i].used)
                if (res == -1 || comp(node[i](x), node[res](x))) res = i;
        }
        return res == -1 ? Line() : node[res];
    }

    size_type size() { return cnt; } // the number of lines
};

template<class T, class Compare>
Compare LiChaoTree<T, Compare>::comp;

int main(void){
	cin.tie(0);
	ios::sync_with_stdio(false);
    using T = tuple<int64, int64, int64>; // -1 -> add, other -> query id

	int64 N, M, Q;
	cin >> N >> M >> Q;
	vector<int64> d(N), d3(3*N+1, 0);
	vector<PLL> bus[2], q(Q);
	REP(i, N) {
	    cin >> d[i];
	}
	REP(i, 3*N) d3[i+1] += d3[i];
    vector<vector<PLL>> ev(N);
	REP(i, M) {
	    char c;
	    int64 b, t;
	    cin >> c >> b >> t;
	    bus[c == 'L'].emplace_back(b, t);
	}
	REP(i, Q) {
	    cin >> q[i].fs >> q[i].sc;
	}
	vector<int64> res(Q, INF_LL);

	REP(dir, 2) {
	    ev = vector<vector<PLL>>(3*N);
	    d3 = vector<int64>(3*N+1, 0);
	    REP(i, N) d3[i+1] = d3[i+N+1] = d3[i+2*N+1] = d[i];
	    REP(i, 3*N) d3[i+1] += d3[i];
	    REP(i, bus[dir].size()) {
	        int64 b, t;
	        tie(b, t) = bus[dir][i]; b--;
	        if (dir == 1) b = (N-b)%N;
	        ev[b].push_back(PLL(-1, t));
            ev[b+N].push_back(PLL(-1, t));
            ev[b+2*N].push_back(PLL(-1, t));
	    }
	    REP(i, Q) {
	        int64 x, y;
	        tie(x, y) = q[i]; x--; y--;
	        if (dir == 1) { x = (N-x)%N; y = (N-y)%N; }
	        if (y >= x) {
	            ev[x].emplace_back(i, y);
	            x += N; y += N;
	        } else {
	            y += N;
	        }
//	        cout << i << ": " << x << "->" << y << endl;
	        ev[x].emplace_back(i, y);
	        ev[x+N].emplace_back(i, y+N);
	    }

	    LiChaoTree<> lct(d3);

        REP(i, 3*N) {
            sort(all(ev[i]));
            REP(j, ev[i].size()) {
                if (ev[i][j].fs == -1) {
//                    cout << i << " " << ev[i][j].sc << " " << -d3[i] * ev[i][j].sc << endl;
                    lct.add(ev[i][j].sc, -d3[i]*ev[i][j].sc);
                } else {
                    auto ret = lct.query(d3[ev[i][j].sc]);
//                    cout << i << " " << ev[i][j].fs << " " << ev[i][j].sc << ": " << ret.fs << " " << ret.sc << endl;
                    if (ret.fs) {
                        chmin(res[ev[i][j].fs], ret.sc);
                    }
                }
            }
        }

	    reverse(all(d));
	}
	REP(i, res.size()) {
	    cout << res[i] << endl;
	}
}
accuracy: 1
time_ms: 410
memory_kb: 62224
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef pair<P,int> T;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define LLINF 1000000000000000000ll
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define all(x) (x).begin(),(x).end()
#define sq(x) ((x)*(x))
#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define repn(i,a,n) for(int (i)=(a);(i)<(int)(n);(i)++)
#define EQ(a,b) (abs((a)-(b))<eps)
#define dmp(x) cerr << __LINE__ << " " << #x << " " << x << endl;
template<class T> void chmin(T& a,const T& b){if(a>b)a=b;}
template<class T> void chmax(T& a,const T& b){if(a<b)a=b;}
template<class T>
void dump(vector<T> &vec){
	for(int i=0;i<vec.size();i++){
		cout << vec[i];
		if(i+1<vec.size())cout << ' ';
		else cout << endl;
	}
	return;
}
template<class T>
void input(vector<T>& vec,int n){
	vec.resize(n);
	for(int i=0;i<n;i++){
		cin >> vec[i];
	}
}
// verifyed EDPC Z
// https://atcoder.jp/contests/dp/tasks/dp_z
// Comptype true : min, false : max
template<class T,bool Comptype = true>
struct LiChaoTree{
	using Line = pair<T,T>;	
	int sz = 1;
	vector<Line> seg;
	vector<T> xs;
	LiChaoTree(){}
	void init(vector<T>& x,T id){
		xs = x;
		int n = x.size();
		while(sz<n)sz<<=1;
		xs.resize(sz,x.back());
		seg.resize(sz*2,Line(T(0),id));
	}
	void dump_tree(){
		for(int i=0;i<seg.size();i++){
			cout << i << ':' << seg[i].fi << ' ' << seg[i].sec << endl;
		}
		// dump(xs);
	}
	static inline T f(Line l,ll x){
		return l.fi*x+l.sec;
	}	
	void add(Line line,int k,int l ,int r){
		int mid = (l+r)/2;
		T lx = xs[l];
		T mx = xs[mid];
		T rx = xs[r-1];
		bool lb = (f(line,lx)<f(seg[k],lx));
		bool mb = (f(line,mx)<f(seg[k],mx));
		bool rb = (f(line,rx)<f(seg[k],rx));
		if((lb==Comptype)&&(rb==Comptype)){
			seg[k] = line;
			return;
		}else if((lb!=Comptype)&&(rb!=Comptype)){
			return;
		}else{
			if(mb==Comptype)swap(seg[k],line);
			if(lb!=mb){
				add(line,2*k+1,l,mid);
			}else{
				add(line,2*k+2,mid,r);
			}
		}
	}
	void add(Line line){
    // cout << "add :" << line.fi << ' ' << line.sec << endl;
		add(line,0,0,sz);
	}
	T query(int k){
		T x = xs[k];
		k += sz-1;
		T ret = f(seg[k],x);
		while(k>0){
			k = (k-1)/2;
			T tmp = f(seg[k],x);
			if((tmp<ret)==Comptype)ret = tmp;
		}
		return ret;
	}
};
int solve(){
	int N;
	ll C;
	vector<ll> h;
	LiChaoTree<ll> seg;
	vector<ll> dp;
	cin >> N >> C;
	input(h,N);
	dp.resize(N,0ll);
	seg.init(h,LLINF);
	seg.add(make_pair(-2*h[0],dp[0]+h[0]*h[0]));
	for(int i=1;i<N;i++){
		// seg.dump_tree();
		dp[i] = h[i]*h[i]+C+seg.query(i);
		// cout << i << ' ' << dp[i] << endl;
		seg.add(make_pair(-2ll*h[i],h[i]*h[i]+dp[i]));
	}
	cout << dp[N-1] << endl;
	return 0;
}
int N,M,Q;
ll d[100100];
ll rui[300100];
struct bus{
  char c;
  ll b,t;
  bus(){}
  bus(char c,ll b,ll t):c(c),b(b),t(t){}
  bool operator < (const bus& a) const{
    return b < a.b;
  }
};
bus bs[200100];
struct query{
  int x,y,id;
  query(){}
  query(int x,int y,int id):x(x),y(y),id(id){}
  bool operator < (const query& a) const{
    return x < a.x;
  }
};
query qs[100100];
ll rans[100100],lans[100100];
vector<ll> qpos;
void solveR(){
  vector<bus> rb;
  for(int i=0;i<M;i++){
    if(bs[i].c=='R'){
      rb.pb(bs[i]);
      rb.pb(bus(bs[i].c,bs[i].b+N,bs[i].t));
      rb.pb(bus(bs[i].c,bs[i].b+2*N,bs[i].t));
    }
  }
  sort(all(rb));
  LiChaoTree<ll> seg;
  seg.init(qpos,LLINF);
  int idx = 0; 
  for(int i=0;i<Q;i++){
    query q = qs[i];
    while(idx<rb.size()&&rb[idx].b<=q.x+N){
      bus& b = rb[idx];
      seg.add(make_pair(b.t,-b.t*rui[b.b]));
      idx++;
    }
    if(q.x<q.y){
      rans[q.id] = seg.query(q.y+N);
    }else{
      rans[q.id] = seg.query(q.y+2*N);
    }
  }
  // cout << "rans" << endl;
  // for(int i=0;i<Q;i++){
  //   cout << rans[i] << endl;
  // }
  return;
}
void solveL(){
  vector<bus> lb;
  for(int i=0;i<M;i++){
    if(bs[i].c=='L'){
      lb.pb(bs[i]);
      lb.pb(bus(bs[i].c,bs[i].b+N,bs[i].t));
      lb.pb(bus(bs[i].c,bs[i].b+2*N,bs[i].t));
    }
  }
  sort(all(lb));
  reverse(all(lb));
  LiChaoTree<ll> seg;
  seg.init(qpos,LLINF);
  int idx = 0; 
  for(int i=Q-1;i>=0;i--){
    query q = qs[i];
    while(idx<lb.size()&&lb[idx].b>=q.x+N){
      bus& b = lb[idx];
      seg.add(make_pair(-b.t,b.t*rui[b.b]));
      idx++;
    }
    if(q.x<q.y){
      lans[q.id] = seg.query(q.y);
    }else{
      lans[q.id] = seg.query(q.y+N);
    }
  }
  // cout << "lans" << endl;
  // for(int i=0;i<Q;i++){
  //   cout << lans[i] << endl;
  // }
  return;
}
int main(){
  cin >> N >> M >> Q;
  for(int i=1;i<=N;i++){
    cin >> d[i];
    rui[i] = rui[i-1]+d[i];
  }
  for(int i=1;i<=N;i++){
    rui[N+i] = rui[N+i-1]+d[i];
  }
  for(int i=1;i<=N;i++){
    rui[2*N+i] = rui[2*N+i-1]+d[i];
  }
  for(int i=0;i<=3*N;i++){
    qpos.pb(rui[i]);
    //cout << rui[i] << ' ';
  }
  //cout << endl;
  for(int i=0;i<M;i++){
    cin >> bs[i].c >> bs[i].b >> bs[i].t;
    bs[i].b--;
  }
  for(int i=0;i<Q;i++){
    int x,y;
    cin >> x >> y;
    x--;y--;
    qs[i] = query(x,y,i);
  }
  sort(qs,qs+Q);
  solveR();
  solveL();
  for(int i=0;i<Q;i++){
   cout << min(lans[i],rans[i]) << endl;
  } 
  return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 48308
final_rank: 16

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
#define MP make_pair
#define PB push_back
#define inf (ll)1000000000007
#define mod 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define int long long
// 単調でない傾きについての convex hull trick
// Li Chao Segment Tree を用いて O(nlog(MAX_A))
template<typename T> class CHT {
private:
    struct node {
        node *left, *right;
        T a, b;
        node() : left(nullptr), right(nullptr) {}
        node(T arg1, T arg2)
            : left(nullptr), right(nullptr), a(arg1), b(arg2) {}
        T f(T x, T a, T b) {
            return a * x + b;
        }
        void add(T l, T r, T a_, T b_) {
            if(f(l,a_,b_) < f(l,a,b)) {
                swap(a,a_), swap(b,b_);
            }
            if(f(r,a,b) <= f(r,a_,b_)) return;
            T mid = (l + r) / 2;
            if(f(mid,a,b) < f(mid,a_,b_)){
                if(!right){
                    right = new node(a_,b_);
                }else{
                    right->add(mid+1,r,a_,b_);
                }
            }else{
                swap(a, a_), swap(b, b_);
                if(!left){
                    left = new node(a_,b_);
                }else{
                    left->add(l,mid,a_,b_);
                }
            }
        }
        T query(T l, T r, T k) {
            if(l == r) return f(k, a, b);
            T ans = f(k, a, b);
            T mid = (l + r) / 2;
            if(k <= mid && left){
                ans = min(ans, left->query(l, mid, k));
            }
            if(k > mid && right){
                ans = min(ans, right->query(mid+1, r, k));
            }
            return ans;
        }
        void rm() {
            if(left) left->rm();
            if(right) right->rm();
            delete this;
        }
    };
    node *root;
    T min_val, max_val;
public:
    // arg1:クエリになげる最小の値, arg2:クエリになげる最大の値
    CHT(T arg1, T arg2)
        : min_val(arg1), max_val(arg2) { root = new node(0,numeric_limits<T>::max()/10); }
    // f(x) = a*x+b を挿入
    void add(T a, T b) {
        return root->add(min_val, max_val, a, b);
    }
    // x=kでの最小値
    T query(T k) {
        return root->query(min_val, max_val, k);
    }
    ~CHT(){
        root->rm();
    }
};

int res[300000];
vector<pair<pair<int,int>,int> > query;
int n,m,q;
    
void solve(vector<int>&R,vector<int>&dist){
    CHT<ll> cht(-inf,inf);
    
    rep(i,n){
        if(i==0)continue;
    
        if(R[i]!=inf){
            //cerr << R[i] << " " <<  R[i]*(dist[n]-dist[i]) << endl; 
            cht.add(R[i],R[i]*(dist[n]-dist[i]));
        }
    }
    int tm = 0;
    sort(query.begin(),query.end());
    int K = 0;
    rep(i,n){
        //cerr<< R[i] << " " << tm << endl;
        if(R[i]!=inf){
            cht.add(R[i],-R[i]*tm);
        }
        while(K!=q&&query[K].first.first == i){
            int from = query[K].first.first;
            int to = query[K].first.second;
            int query_id = query[K].second;
            int d;  
            if(to>from){
                d = dist[to]-dist[from];
            }else{
                d = dist[n] - dist[from] +dist[to];
            }
            //cerr << "d: "<< d << " tm " << tm << endl;
            int ans = cht.query(d+tm);
            //cerr << ans.first << " " << ans.second << endl;
            res[query_id] = min(res[query_id],ans);
            K++;
        }
        tm += dist[i+1]-dist[i];
    }   
    
}


signed main(){
    cin >> n >> m >> q;
    rep(i,q){
        res[i] = inf;
    }
    vector<int> dist(n+1);
    dist[0] = 0;
    rep(i,n){
        int k;
        cin >> k;
        dist[i+1]= dist[i]+k;
    } 
    vector<int> L(n+1,inf),R(n+1,inf);
    rep(i,m){
        char c;
        int b;
        int t;
        cin >> c >> b >> t;
        b--;
        if(c=='R'){
            R[b] = min(t,R[b]);
        }else{
            L[b] = min(t,L[b]);
        }
    }
    rep(i,q){
        int a,b;
        cin >> a >> b;
        a--;b--;
        query.push_back(MP(MP(a,b),i));
    }
    int cnt = 0;
    rep(i,n){
        if(R[i]!=inf)cnt++;
    }
    if(cnt!=0)solve(R,dist);
    // rep(i,q){
    //     cout << res[i] << endl;
    // }
    rep(i,q){
        int a = query[i].first.first;
        int b = query[i].first.second;
        if(a!=0){
            a = n-a;
        }
        if(b!=0){
            b = n-b;
        }
        query[i].first.first = a;
        query[i].first.second = b;
    }
    vector<int> L2(n);
    vector<int> dist2(n+1);
    rep(i,n){
        if(i==0){
            L2[i] = L[i];
        }else{
            L2[i] = L[n-i];
        }
    }
    rep(i,n){
        dist2[i] = dist[n] - dist[n-i];
    }
    dist2[n] = dist[n];
    // rep(i,n){
    //     cerr << dist2[i] << " ";
    // }
    // cerr << endl;
    
    int cnt2 = 0;
    rep(i,n){
        if(L[i]!=inf)cnt2++;
    }
    if(cnt2!=0)solve(L2,dist2);
    rep(i,q){
        cout << res[i] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 15236
final_rank: 11

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef pair<ll, ll> LP;
typedef vector<ll> vec;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-5;
const ld pi = acos(-1.0);

struct LiChaoTree {
	int sz;
	struct Node {
		int l, r;
		Node* chl; Node* chr;
		LP val;
		Node(int l, int r) :l(l), r(r) {
			val = { 0,INF };
			chl = chr = NULL;
		}
	};
	Node* root;
	LiChaoTree() {
		int max_n = 1e8 + 1;
		sz = 1;
		while (sz < max_n)sz <<= 1;
		root = new Node(0, sz);
	}
	ll calc(LP a, int x) {
		return a.first*x + a.second;
	}
	void add(Node* node, LP a) {
		if (!node)return;
		int l = node->l, r = node->r;
		int m = (l + r) / 2;
		//そのノードでの最小値
		if (calc(node->val, m) > calc(a, m))swap(node->val, a);
		if (r - l == 1)return;
		//左側をさらに更新しなきゃ
		if (calc(node->val, l) > calc(a, l)) {
			if (!node->chl)node->chl = new Node(l, m);
			add(node->chl, a);
		}
		else if (calc(node->val, r) > calc(a, r)) {
			if (!node->chr)node->chr = new Node(m, r);
			add(node->chr, a);
		}
	}
	void add(LP a) {
		add(root, a);
	}
	ll query(int x) {
		ll ret = INF;
		Node* node = root;
		while (node) {
			ret = min(ret, calc(node->val, x));
			int m = (node->l + node->r) / 2;
			if (x < m) {
				node = node->chl;
			}
			else {
				node = node->chr;
			}
		}
		return ret;
	}
};

void solve() {
	int n, m, q; cin >> n >> m >> q;
	vector<int> d(n);
	rep(i, n) {
		cin >> d[i];
	}
	vector<int> rd(n+1);
	rep(i, n) {
		rd[i + 1] = rd[i] + d[i];
	}
	vector<vector<int>> vl(n), vr(n);
	rep(i, m) {
		char c; int b, t;
		cin >> c >> b >> t; b--;
		if (c == 'L') {
			vl[b].push_back(t);
		}
		else {
			vr[b].push_back(t);
		}
	}
	vector<ll> ans(q);
	fill(ans.begin(), ans.end(), INF);
	vector<vector<P>>que(n);
	rep(i, q) {
		int x, y; cin >> x >>y; x--; y--;
		que[x].push_back({ y,i });

	}
	if (vr.size()) {
		LiChaoTree cr;
		rep(i, n) {
			int dist = rd[n]-rd[i];
			rep(j, vr[i].size()) {
				int  t= vr[i][j];
				cr.add({ t,(ll)t*dist });
			}
		}
		rep(i, n) {
			rep(j, vr[i].size()) {
				int t = vr[i][j];
				cr.add({ t,-(ll)t*rd[i] });
			}
			rep(j, que[i].size()) {
				int to = que[i][j].first;
				int id = que[i][j].second;
				ll x = rd[to];
				if (to < i)x += rd[n];
				//if (x < 0)x += rd[n];
				ans[id] = min(ans[id], cr.query(x));
			}
		}
	}
	if (vl.size()) {
		LiChaoTree cl;
		per(i, n) {
			int dist = rd[i];
			rep(j, vl[i].size()) {
				int t = vl[i][j];
				cl.add({ t,(ll)t*dist });
			}
		}
		per(i, n) {
			rep(j, vl[i].size()) {
				int t = vl[i][j];
				cl.add({ t,-(ll)t*(rd[n] - rd[i]) });
			}
			rep(j, que[i].size()) {
				int to = que[i][j].first;
				int id = que[i][j].second;
				ll x = rd[n]-rd[to];
				if (i < to)x += rd[n];
				//if (x < 0)x += rd[n];
				ans[id] = min(ans[id], cl.query(x));
			}
		}
	}
	rep(i, q) {
		cout << ans[i] << endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 18820
final_rank: 4

code_snippet: // う？笑
#include <bits/stdc++.h>

using namespace std;

using int64 = long long;
const int mod = 1e9 + 7;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}

template< typename F >
struct FixPoint : F {
  FixPoint(F &&f) : F(forward< F >(f)) {}

  template< typename... Args >
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward< Args >(args)...);
  }
};

template< typename F >
inline decltype(auto) MFP(F &&f) {
  return FixPoint< F >{forward< F >(f)};
}

template< typename T >
struct LiChaoTree {
  struct Line {
    T a, b;

    Line(T a, T b) : a(a), b(b) {}

    inline T get(T x) const { return a * x + b; }

    inline bool over(const Line &b, const T &x) const {
      return get(x) < b.get(x);
    }
  };

  vector< T > xs;
  vector< Line > seg;
  int sz;

  LiChaoTree(const vector< T > &x, T INF) : xs(x) {
    sz = 1;
    while(sz < xs.size()) sz <<= 1;
    while(xs.size() < sz) xs.push_back(xs.back() + 1);
    seg.assign(2 * sz - 1, Line(0, INF));
  }

  void update(Line &x, int k, int l, int r) {
    int mid = (l + r) >> 1;
    auto latte = x.over(seg[k], xs[l]), malta = x.over(seg[k], xs[mid]);
    if(malta) swap(seg[k], x);
    if(l + 1 >= r) return;
    else if(latte != malta) update(x, 2 * k + 1, l, mid);
    else update(x, 2 * k + 2, mid, r);
  }

  void update(T a, T b) { // ax+b
    Line l(a, b);
    update(l, 0, 0, sz);
  }

  T query(int k) { // xs[k]
    const T x = xs[k];
    k += sz - 1;
    T ret = seg[k].get(x);
    while(k > 0) {
      k = (k - 1) >> 1;
      ret = min(ret, seg[k].get(x));
    }
    return ret;
  }
};


int main() {
  int N, M, Q;
  cin >> N >> M >> Q;
  vector< int64 > DD(N);
  cin >> DD;

  vector< char > C(M);
  vector< int64 > B(M), T(M);
  for(int i = 0; i < M; i++) {
    cin >> C[i] >> B[i] >> T[i];
    --B[i];
  }
  vector< int64 > X(Q), Y(Q);
  for(int i = 0; i < Q; i++) {
    cin >> X[i] >> Y[i];
    --X[i], --Y[i];
  }

  vector< int64 > ans(Q, infll);

  auto solve = [&]() {

    vector< pair< int64, int64 > > latte, malta;

    for(int i = 0; i < M; i++) {
      if(C[i] == 'R') latte.emplace_back(B[i], T[i]);
      else malta.emplace_back(B[i], T[i]);
    }
    vector< int64 > D(N + 1);
    for(int i = 1; i <= N; i++) D[i] = DD[i - 1];
    for(int i = 1; i <= N; i++) D[i] += D[i - 1];


    vector< int64 > uku_chan[4];
    vector< int > ord;
    for(int i = 0; i < Q; i++) {
      if(X[i] < Y[i]) {
        ord.emplace_back(i);
        uku_chan[0].emplace_back(D[Y[i]]);
        uku_chan[1].emplace_back(D[Y[i]] + D[N]);
        uku_chan[2].emplace_back(-D[Y[i]] + D[N]);
        uku_chan[3].emplace_back(-D[Y[i]] + 2 * D[N]);
      }
    }
    if(ord.empty()) return;

    for(int i = 0; i < 4; i++) {
      sort(begin(uku_chan[i]), end(uku_chan[i]));
      uku_chan[i].erase(unique(begin(uku_chan[i]), end(uku_chan[i])), end(uku_chan[i]));
    }

    using CHT = LiChaoTree< int64 >;

    sort(begin(latte), end(latte), [&](auto p, auto q) {
      return p.first < q.first;
    });
    sort(begin(malta), end(malta), [&](auto p, auto q) {
      return p.first < q.first;
    });

    // ソートをします　つまらねえ
    // ああ　うく
    sort(begin(ord), end(ord), [&](int a, int b) {
      return X[a] < X[b];
    });

    {
      CHT cht(uku_chan[0], infll);
      int ptr = 0;
      for(int i : ord) {
        int x = X[i];
        int y = Y[i];
        while(ptr < latte.size() && latte[ptr].first <= x) {
          auto &p = latte[ptr];
          cht.update(p.second, -p.second * D[p.first]);
          ++ptr;
        }
        y = lower_bound(begin(uku_chan[0]), end(uku_chan[0]), D[y]) - begin(uku_chan[0]);
        chmin(ans[i], cht.query(y));
      }
    }

    {
      CHT cht(uku_chan[1], infll);

      int ptr = (int) latte.size() - 1;
      for(int p = (int) ord.size() - 1; p >= 0; p--) {
        int i = ord[p];
        int x = X[i];
        int y = Y[i];
        while(ptr >= 0 && latte[ptr].first > x) {
          auto &p = latte[ptr];
          cht.update(p.second, -p.second * D[p.first]);
          --ptr;
        }
        y = lower_bound(begin(uku_chan[1]), end(uku_chan[1]), D[y] + D[N]) - begin(uku_chan[1]);
        chmin(ans[i], cht.query(y));
      }
    }


    {
      CHT cht(uku_chan[2], infll);
      int ptr = (int) malta.size() - 1;
      for(int p = (int) ord.size() - 1; p >= 0; p--) {
        int i = ord[p];
        int x = X[i];
        int y = Y[i];
        while(ptr >= 0 && malta[ptr].first >= x) {
          auto &p = malta[ptr];
          cht.update(p.second, p.second * D[p.first]);
          --ptr;
        }
        y = lower_bound(begin(uku_chan[2]), end(uku_chan[2]), -D[y] + D[N]) - begin(uku_chan[2]);
        chmin(ans[i], cht.query(y));
      }
    }

    {
      CHT cht(uku_chan[3], infll);
      int ptr = 0;
      for(int i : ord) {
        int x = X[i];
        int y = Y[i];
        while(ptr < malta.size() && malta[ptr].first < x) {
          auto &p = malta[ptr];
          cht.update(p.second, p.second * D[p.first]);
          ++ptr;
        }
        y = lower_bound(begin(uku_chan[3]), end(uku_chan[3]), 2 * D[N] - D[y]) - begin(uku_chan[3]);
        chmin(ans[i], cht.query(y));
      }
    }

    /*
    for(int i = 0; i < Q; i++) {
      int x = X[i];
      int y = Y[i];
      if(x < y) {
        int64 ret = infll;
        /*
        for(auto &p : latte) {
          if(p.first <= x) ret = min(ret, p.second * (D[y] - D[p.first]));
          else ret = min(ret, p.second * ((D[N] - D[p.first]) + D[y]));
        }
        for(auto &p : malta) {
          if(x <= p.first) ret = min(ret, p.second * (D[p.first] + (D[N] - D[y])));
          else ret = min(ret, p.second * (D[p.first] + D[N] + (D[N] - D[y])));
        }



        /*for(auto &p : latte) {
          if(p.first <= x) ret = min(ret, (p.second * D[y]) - p.second * D[p.first]);
          else ret = min(ret, (p.second * (D[y] + D[N])) - p.second * D[p.first]);
        }
        for(auto &p : malta) {
          if(x <= p.first) ret = min(ret, p.second * D[p.first] + (p.second * (D[N] - D[y])));
          else ret = min(ret, p.second * D[p.first] + (p.second * (2 * D[N] - D[y])));
        }

        chmin(ret, latte_seg.query(0, x + 1, D[y]));
        chmin(ret, latte_seg.query(x + 1, N, D[y] + D[N]));
        chmin(ret, malta_seg.query(x, N, D[N] - D[y]));
        chmin(ret, malta_seg.query(0, x, 2 * D[N] - D[y]));


        ans[i] = ret;
      }
    }
    */
  };


  solve();

  for(int i = 0; i < M; i++) {
    C[i] = (C[i] == 'R' ? 'L' : 'R');
    B[i] = N - B[i] - 1;
  }
  for(int i = 0; i < Q; i++) {
    X[i] = N - X[i] - 1;
    Y[i] = N - Y[i] - 1;
  }
  vector< int64 > EE;
  for(int i = 0; i < N; i++) EE.emplace_back(DD[(N + N + N + N - i - 2) % N]);
  EE.swap(DD);
  solve();
  for(auto &p : ans) cout << p << endl;
}
accuracy: 1
time_ms: 220
memory_kb: 16780
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double Db;
typedef complex<Db> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;
#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

ll N,M,Q;
vector<ll> dist;
vector<pll> bus_L;
vector<pll> bus_R;
vector<pll> query;
vector<ll> ans;

/*
  O(QlogN+N)
  追加する直線の傾きが狭義単調減少であること
  maxを求めるときは値と傾きに-1をかけること
*/
template<typename T>
class Comvex_Hull_Trick{
public:
  typedef pair<T,T> line; //y切片,傾き
  deque<line> D;
    
  inline T point(const line &L,const T &x) const {return L.F+L.S*x;}
    
  inline bool is_need(const line &A,const line &B,const line &C) const {
    return (double)(C.F-A.F)*(A.S-B.S)>(double)(B.F-A.F)*(A.S-C.S);
  }
    

  Comvex_Hull_Trick(){}
    
  void add_line(const line &L){
    while(!D.empty() && D.front().S>=L.S){D.pop_front();}
    while(D.size()>=2 && !is_need(L,D[0],D[1])){D.pop_front();}
    D.push_front(L);
  }
    
  T search(const T &x) const {
    ll l=0;
    ll r=(int)D.size()-1;
    while(l+1<r){
      ll m=l+(r-l)/2;
      if(point(D[m],x)<point(D[m+1],x)){r=m;}
      else{l=m+1;}
    }
    for(ll i=l;i<r;i++){
      if(point(D[i],x)<point(D[i+1],x)){return point(D[i],x);}
    }
    return point(D[r],x);
  }
    
  bool empty() const {return D.empty();}
};

void cul(vector<pll> &B){
  sort(B.begin(),B.end());
  vector<pair<pll,ll>> qr(2*Q);
  for(int i=0;i<2*Q;i++){qr[i]={{query[i%Q].F+i/Q*N,query[i%Q].S},i%Q};}
  for(auto &I:qr){while(I.F.F>I.F.S){I.F.S+=N;}}
  sort(qr.begin(),qr.end());
  vector<ll> D(3*N,0);
  for(ll i=1;i<3*N;i++){D[i]=dist[(i-1)%N];}
  for(ll i=1;i<3*N;i++){D[i]+=D[i-1];}
  Comvex_Hull_Trick<ll> cht;
  int qi=0;
  int bi=0;
  for(int i=0;i<2*N;i++){
    while(bi<(int)B.size() && B[bi].F==i){cht.add_line({-1LL*D[B[bi].F]*B[bi].S,B[bi].S}); bi++;}
    while(qi<(int)qr.size() && qr[qi].F.F==i){
      if(!cht.empty()){
        ans[qr[qi].S]=min(ans[qr[qi].S],cht.search(D[qr[qi].F.S]));
      }
      qi++;
    }
  }
}


int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin>>N>>M>>Q;
  dist.resize(N);
  query.resize(Q);
  ans.resize(Q,1e18);
  cin>>dist;
  for(int i=0;i<M;i++){
    char c;
    int b,t;
    cin>>c>>b>>t;
    b--;
    if(c=='R'){
      bus_L.push_back({b,t});
    }
    else{
      bus_R.push_back({(N-b)%N,t});
    }
  }
  cin>>query;
  for(auto &I:query){I.F--; I.S--;}
  cul(bus_L);
  reverse(dist.begin(),dist.end());
  for(auto &I:query){I.F=(N-I.F)%N; I.S=(N-I.S)%N;}
  cul(bus_R);
  for(auto &I:ans){cout<<I<<endl;}
  
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 14412
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double Db;
typedef complex<Db> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;
#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

ll N,M,Q;
vector<ll> dist;
vector<pll> bus_L;
vector<pll> bus_R;
vector<pll> query;
vector<ll> ans;

/*
  O(QlogN+N)
  追加する直線の傾きが狭義単調減少であること
  maxを求めるときは値と傾きに-1をかけること
*/
template<typename T>
class Comvex_Hull_Trick{
public:
  typedef pair<T,T> line; //y切片,傾き
  deque<line> D;
    
  inline T point(const line &L,const T &x) const {return L.F+L.S*x;}
    
  inline bool is_need(const line &A,const line &B,const line &C) const {
    return __int128(C.F-A.F)*(A.S-B.S)>__int128(B.F-A.F)*(A.S-C.S);
  }
    

  Comvex_Hull_Trick(){}
    
  void add_line(const line &L){
    while(!D.empty() && D.front().S>=L.S){D.pop_front();}
    while(D.size()>=2 && !is_need(L,D[0],D[1])){D.pop_front();}
    D.push_front(L);
  }
    
  T search(const T &x) const {
    ll l=0;
    ll r=(int)D.size()-1;
    while(l+1<r){
      ll m=l+(r-l)/2;
      if(point(D[m],x)<point(D[m+1],x)){r=m;}
      else{l=m+1;}
    }
    for(ll i=l;i<r;i++){
      if(point(D[i],x)<point(D[i+1],x)){return point(D[i],x);}
    }
    return point(D[r],x);
  }
    
  bool empty() const {return D.empty();}
};

void cul(vector<pll> &B){
  sort(B.begin(),B.end());
  vector<pair<pll,ll>> qr(2*Q);
  for(int i=0;i<2*Q;i++){qr[i]={{query[i%Q].F+i/Q*N,query[i%Q].S},i%Q};}
  for(auto &I:qr){while(I.F.F>I.F.S){I.F.S+=N;}}
  sort(qr.begin(),qr.end());
  vector<ll> D(3*N,0);
  for(ll i=1;i<3*N;i++){D[i]=dist[(i-1)%N];}
  for(ll i=1;i<3*N;i++){D[i]+=D[i-1];}
  Comvex_Hull_Trick<ll> cht;
  int qi=0;
  int bi=0;
  for(int i=0;i<2*N;i++){
    while(bi<(int)B.size() && B[bi].F==i){cht.add_line({-1LL*D[B[bi].F]*B[bi].S,B[bi].S}); bi++;}
    while(qi<(int)qr.size() && qr[qi].F.F==i){
      if(!cht.empty()){
        ans[qr[qi].S]=min(ans[qr[qi].S],cht.search(D[qr[qi].F.S]));
      }
      qi++;
    }
  }
}


int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin>>N>>M>>Q;
  dist.resize(N);
  query.resize(Q);
  ans.resize(Q,1e18);
  cin>>dist;
  for(int i=0;i<M;i++){
    char c;
    int b,t;
    cin>>c>>b>>t;
    b--;
    if(c=='R'){
      bus_L.push_back({b,t});
    }
    else{
      bus_R.push_back({(N-b)%N,t});
    }
  }
  cin>>query;
  for(auto &I:query){I.F--; I.S--;}
  cul(bus_L);
  reverse(dist.begin(),dist.end());
  for(auto &I:query){I.F=(N-I.F)%N; I.S=(N-I.S)%N;}
  cul(bus_R);
  for(auto &I:ans){cout<<I<<endl;}
  
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 14412
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;
#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

ll N,M,Q;
vector<ll> dist;
vector<pll> bus_L;
vector<pll> bus_R;
vector<pll> query;
vector<ll> ans;

/*
  O(QlogN+N)
  追加する直線の傾きが狭義単調減少であること
  maxを求めるときは値と傾きに-1をかけること
*/
template<typename T>
class Comvex_Hull_Trick{
public:
  typedef pair<T,T> line; //y切片,傾き
  deque<line> D;
    
  inline T point(const line &L,const T &x) const {return L.F+L.S*x;}
    
  inline bool is_need(const line &A,const line &B,const line &C) const {
    return (C.F-A.F)*(A.S-B.S)>(B.F-A.F)*(A.S-C.S);
  }
    

  Comvex_Hull_Trick(){}
    
  void add_line(const line &L){
    while(!D.empty() && D.front().S>=L.S){D.pop_front();}
    while(D.size()>=2 && !is_need(L,D[0],D[1])){D.pop_front();}
    D.push_front(L);
  }
    
  T search(const T &x) const {
    ll l=0;
    ll r=(int)D.size()-1;
    while(l+1<r){
      ll m=l+(r-l)/2;
      if(point(D[m],x)<point(D[m+1],x)){r=m;}
      else{l=m+1;}
    }
    for(ll i=l;i<r;i++){
      if(point(D[i],x)<point(D[i+1],x)){return point(D[i],x);}
    }
    return point(D[r],x);
  }
    
  bool empty() const {return D.empty();}
};

void cul(vector<pll> &B){
  sort(B.begin(),B.end());
  vector<pair<pll,ll>> qr(2*Q);
  for(int i=0;i<2*Q;i++){qr[i]={{query[i%Q].F+i/Q*N,query[i%Q].S},i%Q};}
  for(auto &I:qr){while(I.F.F>I.F.S){I.F.S+=N;}}
  sort(qr.begin(),qr.end());
  vector<ll> D(3*N,0);
  for(ll i=1;i<3*N;i++){D[i]=dist[(i-1)%N];}
  for(ll i=1;i<3*N;i++){D[i]+=D[i-1];}
  Comvex_Hull_Trick<ll> cht;
  int qi=0;
  int bi=0;
  for(int i=0;i<2*N;i++){
    while(bi<(int)B.size() && B[bi].F==i){cht.add_line({-1LL*D[B[bi].F]*B[bi].S,B[bi].S}); bi++;}
    while(qi<(int)qr.size() && qr[qi].F.F==i){
      if(!cht.empty()){
        ans[qr[qi].S]=min(ans[qr[qi].S],cht.search(D[qr[qi].F.S]));
      }
      qi++;
    }
  }
}


int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin>>N>>M>>Q;
  dist.resize(N);
  query.resize(Q);
  ans.resize(Q,1e18);
  cin>>dist;
  for(int i=0;i<M;i++){
    char c;
    int b,t;
    cin>>c>>b>>t;
    b--;
    if(c=='R'){
      bus_L.push_back({b,t});
    }
    else{
      bus_R.push_back({(N-b)%N,t});
    }
  }
  cin>>query;
  for(auto &I:query){I.F--; I.S--;}
  cul(bus_L);
  reverse(dist.begin(),dist.end());
  for(auto &I:query){I.F=(N-I.F)%N; I.S=(N-I.S)%N;}
  cul(bus_R);
  for(auto &I:ans){cout<<I<<endl;}
  
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 14524
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

template<typename T,bool isMin>
struct NonmonotonicConvexHullTrick {
  using number = double;
  static constexpr number INF = numeric_limits<T>::max();
  struct Line {
    T m,b,val;
    number x;
    bool q;
    Line(T m=0,T b=0):m(m),b(b),val(0),x(-INF),q(false){}
    
    T eval(T x) const{return m*x+b;}
    bool parallel(const Line &l) const{return m==l.m;}
    number intersect(const Line &l) const{
      return parallel(l)?number(INF):number(l.b-b)/number(m-l.m);
    }
    bool operator<(const Line &l) const{
      if(l.q) return x<l.val;
      return m<l.m;
    }
  };
  
  set<Line> hull;
  using iter = typename set<Line>::iterator;

  bool cPrev(iter it){return it!=hull.begin();}
  bool cNext(iter it){return it!=hull.end()&&next(it)!=hull.end();}

  bool bad(const Line &l1,const Line &l2,const Line &l3){
    return l1.intersect(l3) <= l1.intersect(l2);
  }
  bool bad(iter it){
    return cPrev(it)&&cNext(it)&&bad(*prev(it),*it,*next(it));
  }

  iter update(iter it){
    if(!cPrev(it)) return it;
    number x=it->intersect(*prev(it));
    Line tmp(*it);
    tmp.x=x;
    it=hull.erase(it);
    return hull.insert(it,tmp);
  }
  
  void addLine(T m,T b){
    if(isMin) m=-m,b=-b;
    Line l(m,b);
    iter it=hull.lower_bound(l);
    if(it!=hull.end()&&l.parallel(*it)){
      if(it->b<b) it=hull.erase(it);
      else return;
    }
    it=hull.insert(it,l);
    if(bad(it)){
      hull.erase(it);
      return;
    }
    while(cPrev(it)&&bad(prev(it))) hull.erase(prev(it));
    while(cNext(it)&&bad(next(it))) hull.erase(next(it));

    it=update(it);
    if(cPrev(it)) update(prev(it));
    if(cNext(it)) update(next(it));
  }

  bool empty() const{
    return hull.empty();
  }

  T query(T x){
    assert(!empty());
    Line q;
    q.val=x;q.q=1;
    iter it=--hull.lower_bound(q);
    if(isMin) return -(it->eval(x));
    return it->eval(x);
  }
};

using P = pair<int, int>;

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int N, M, Q;
  cin >> N >> M >> Q;

  vector<int> d(N), sum(N, 0);
  int all = 0;
  for ( int i = 0; i < N; i++ ) {
    cin >> d[i];
    all += d[i];
    if ( i ) sum[i] = d[i-1]+sum[i-1];    
  }

  vector<P> L, R;
  for ( int i = 0; i < M; i++ ) {
    char c;
    int b, t;
    cin >> c >> b >> t;
    b--;    
    if ( c == 'L' ) L.emplace_back(P(b, t));
    else R.emplace_back(P(b, t));    
  }

  vector<P> qs(Q);
  unordered_map<int, int> ans[N];  
  for ( int i = 0; i < Q; i++ ) {
    cin >> qs[i].first >> qs[i].second;
    qs[i].first--; qs[i].second--;
    ans[qs[i].first][qs[i].second] = 1e18;    
  }

  vector<P> ori = qs;  
  if ( R.size() ) {    
    NonmonotonicConvexHullTrick<int, true> cht;    
    sort(R.begin(), R.end());
    sort(qs.begin(), qs.end());    
    for ( int i = 0; i < (int)R.size(); i++ ) {
      int b = R[i].first, t = R[i].second;      
      cht.addLine(t, (all-sum[b])*t);
    }

    int now = 0;
    for ( P e : qs ) {
      int x = e.first, y = e.second;      
      while ( now < R.size() && R[now].first <= x ) {
	int b = R[now].first, t = R[now].second;      
	cht.addLine(t, -sum[b]*t);
	now++;
      }

      int gl = sum[y];
      if ( x > y ) gl += all;

      ans[x][y] = cht.query(gl);      
    }
  }

  if ( L.size() ) {       
    NonmonotonicConvexHullTrick<int, true> cht;    
    sort(L.begin(), L.end(), greater<P>());    
    sort(qs.begin(), qs.end(), greater<P>());    
    for ( int i = 0; i < (int)L.size(); i++ ) {
      int b = L[i].first, t = L[i].second;      
      cht.addLine(-t, sum[b]*t);
    }

    int now = 0;
    for ( P e : qs ) {
      int x = e.first, y = e.second;      
      while ( now < L.size() && L[now].first >= x ) {
	int b = L[now].first, t = L[now].second;      
	cht.addLine(-t, -(all-sum[b])*t);
	now++;	
      }

      int gl = -(all-sum[y]);
      if ( x < y ) gl -= all;

      ans[x][y] = min(ans[x][y], cht.query(gl));      
    }
  }

  for ( P e : ori ) {
    cout << ans[e.first][e.second] << endl;    
  }
  
  return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 27288
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

//INSERT ABOVE HERE
signed main(){
  Int n,m,q;
  cin>>n>>m>>q;

  vector<Int> ds(n);
  for(Int i=0;i<n;i++) cin>>ds[i];
  for(Int i=0;i<n;i++) ds.emplace_back(Int(ds[i]));
  for(Int i=0;i<n;i++) ds.emplace_back(Int(ds[i]));

  vector<Int> sm(n*3+1,0);
  for(Int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<Int> bs(m),ts(m);
  for(Int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector<Int> xs(q),ys(q);
  for(Int i=0;i<q;i++) cin>>xs[i]>>ys[i],xs[i]--,ys[i]--;


  const Int INF = 1e18;
  vector<Int> R(n*3,INF),L(n*3,INF);
  for(Int i=0;i<m;i++){
    if(cs[i]=='R'){
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  const Int len=min(n,3000LL);

  using P = pair<Int, Int>;
  vector<P> TR,TL;
  for(Int i=0;i<n;i++){
    TR.emplace_back(R[i],i);
    TL.emplace_back(L[i],i);
  }
  sort(TR.begin(),TR.end());
  sort(TL.begin(),TL.end());
  TR.resize(len);
  TL.resize(len);

  vector<Int> ans(q,INF);
  // use R
  for(Int i=0;i<q;i++){
    Int x=xs[i],y=ys[i];
    if(x>y) y+=n;
    for(Int s=x+n-len;s<=x+n;s++){
      if(R[s]==INF) continue;
      chmin(ans[i],(sm[y+n]-sm[s])*R[s]);
    }
    for(auto p:TR){
      Int s=p.second;
      if(s+n<=x+n) s+=n;
      if(R[s]==INF) continue;
      chmin(ans[i],(sm[y+n]-sm[s])*R[s]);
    }
  }
  // use L
  for(Int i=0;i<q;i++){
    Int x=xs[i],y=ys[i];
    if(x<y) x+=n;
    for(Int s=x;s<=x+len;s++){
      if(L[s]==INF) continue;
      chmin(ans[i],(sm[s]-sm[y])*L[s]);
    }
    for(auto p:TL){
      Int s=p.second;
      while(s<x) s+=n;
      if(L[s]==INF) continue;
      chmin(ans[i],(sm[s]-sm[y])*L[s]);
    }
  }

  for(Int i=0;i<q;i++) cout<<ans[i]<<"\n";
  cout<<flush;
  return 0;
}
accuracy: 0.6037735849056604
time_ms: 40
memory_kb: 18024
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int inf = (1LL<<50)+1e9; // ~ 1.15 * 1e18
const Int INF = (1LL<<50)+1e9; // ~ 1.15 * 1e18
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
//INSERT ABOVE HERE

template <typename T, T INF>
class ConvexHullTrick{
public:
  typedef pair<T, T> P;
  Int MAX_N;
  set<P> L; //!!!!!!!!!!!!!!!!!!!!!!
  ConvexHullTrick(){};
  inline Int size(){return L.size();}

  inline T getY(const P l, T x){return l.first * x + l.second;}

  inline bool check(const P &l1, const P &l2, const P &l3){
    return
      (l2.first - l1.first) * (l3.second - l2.second) >=
      (l2.second - l1.second) * (l3.first - l2.first);
  }

  void insert(T a, T b){
    if(a == INF) return;
    const P line = P(a, b);
    {//同じ傾きの切片が小さいものがあったら何もしない
      auto p = L.lower_bound(P(a, -INF));
      if(p != L.end() && p->first == a && p->second <= b) return;
    }

    {//同じ傾きの切片が大きいものがあったら消す
      auto p = L.lower_bound(line);
      if(p != L.end()  && p->first == a) L.erase(p);
    }

    L.insert(line);

    {//lineの必要性判定
      auto l = L.lower_bound(line);
      auto r = l;
      if(l != L.end() && l != L.begin()){
        l--; r++;
        if(check(*r, line, *l)) {
          L.erase(line);
          return;
        }
      }
    }

    {//左に向かってcheck(l1, l2, l3)し削除する
      auto p = L.lower_bound(line);
      while(1){
        auto l1 = p;
        if(p == L.begin()) break;
        auto l2 = --p;
        if(p == L.begin()) break;
        auto l3 = --p;
        if(!check(*l1, *l2, *l3)) break;
        L.erase(l2);
        p = l1;
      }
    }

    {//右に向かってcheck(l1, l2, l3)し削除する
      auto p = L.lower_bound(line);
      while(1){
        auto l3 = p;
        auto l2 = ++p;
        if(p == L.end()) break;
        auto l1 = ++p;
        if(p == L.end()) break;
        if(!check(*l1, *l2, *l3)) break;
        L.erase(l2);
        p = l3;
      }
    }
  }

  void insert(P l){insert(l.first, l.second);}

  T get(T x){
    auto it = L.begin();
    while(it != L.end()){
      auto l = it;
      auto r = ++it;
      if(r == L.end()) break;
      if(getY(*l, x) < getY(*r, x)) break;
    }
    return getY(*(--it), x);
  }
};


template<typename T>
class CumulativeSum{
public:
  int n;
  vector<T> sum;
  vector<T> A;
  int added;
  CumulativeSum():n(-1),added(0){}
  CumulativeSum(int n):n(n), sum(n+1), A(n+1),added(0){}
  CumulativeSum(const vector<T> &B):n(B.size()), sum(n+1), A(n+1),added(0){
    for(int i=1;i<=n;i++) sum[i] = sum[i-1] + B[i-1];
  }

  void apply(){
    for(int i=1;i<=n;i++) A[i] = A[i] + A[i-1];
    for(int i=1;i<=n;i++) A[i] = A[i] + A[i-1];
    for(int i=1;i<=n;i++) sum[i] = sum[i] + A[i-1];
    added = 0; A.clear(); A.resize(n+1);
  }

  //[l, r)にxを加算
  void add(int l, int r, T x){
    added = 1;
    assert(l <= r && 0 <= l && r <= n);
    A[l] = A[l] + x;
    A[r] = A[r] - x;
  }

  //[l, r)の和を得る
  T get(int l,int r){
    assert(l<=r && 0<=l && r<=n);
    if(added) apply();
    return sum[r] - sum[l];
  }
};

vector<Int> solve(Int N, vector<Int> D, vector<P> R, vector<P> Q){
  if(R.size() == 0) return vector<Int>(Q.size(), INF);
  CumulativeSum<Int> sumD(N*2);
  for(Int i=0;i<2*N;i++) sumD.add(i, i+1, D[i%N]);

  vector<vector<P> > Query(N);
  for(Int i=0;i<(Int)Q.size();i++){
    Int from, to; tie(from, to) = Q[i];
    Query[from].emplace_back(to, i);
  }

  vector<Int> Bus(N, INF);
  for(auto p:R){
    Int b, t; tie(b, t) = p;
    Bus[b] = min(Bus[b], t);
  }

  vector<P> lines(2 * N);
  for(Int i=0;i<2 * N;i++){
    Int a = Bus[i%N];
    Int b = -sumD.get(0, i) * a;
    lines[i] = P(a, b);
  }

  ConvexHullTrick<Int, INF> cht;
  for(Int i=0;i<N;i++) if(lines[i].first != INF) cht.insert(lines[i]);

  vector<Int> res(Q.size());
  for(Int from=0;from<N;from++){
    if(lines[N + from].first != INF) cht.insert(lines[N + from]);
    for(auto p:Query[from]){
      Int to, idx; tie(to, idx) = p;
      Int ofset = sumD.get(0, N+from);
      Int x = ofset + sumD.get(from, from<=to? to:(to+N));
      Int ans = cht.get(x);
      res[idx] = ans;
    }
  }

  return res;
}

signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  Int N, M, Q;
  cin>>N>>M>>Q;

  vector<Int> rD(N);
  cin>>rD;
  vector<Int> D = rD;
  reverse(rD.begin(), rD.end());

  vector<P> rR;
  vector<P> R;
  for(Int i=0;i<M;i++){
    char ch;
    Int b, t;
    cin>>ch>>b>>t; b--;
    if(ch == 'R') R.emplace_back(b, t);
    if(ch == 'L') rR.emplace_back((N - b)%N, t);
  }

  vector<P> Query;
  vector<P> rQuery;
  for(Int i=0;i<Q;i++){
    Int x, y;
    cin>>x>>y; x--, y--;
    Query.emplace_back(x, y);
    rQuery.emplace_back((N - x)%N, (N - y)%N);
  }

  vector<Int> ansB = solve(N, rD, rR, rQuery);
  vector<Int> ansA = solve(N, D, R, Query);

  for(Int i=0;i<Q;i++){
    Int ans = min(ansA[i], ansB[i]);
    cout<<ans<<endl;
  }

  return 0;
}
accuracy: 0.9622641509433962
time_ms: 240
memory_kb: 32076
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<50)+1e9; // ~ 1.15 * 1e18
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
//INSERT ABOVE HERE

template<typename T>
class CumulativeSum{
public:
  Int n;
  vector<T> sum;
  vector<T> A;
  Int added;
  CumulativeSum():n(-1),added(0){}
  CumulativeSum(Int n):n(n), sum(n+1), A(n+1),added(0){}
  CumulativeSum(const vector<T> &B):n(B.size()), sum(n+1), A(n+1),added(0){
    for(Int i=1;i<=n;i++) sum[i] = sum[i-1] + B[i-1];
  }

  void apply(){
    for(Int i=1;i<=n;i++) A[i] = A[i] + A[i-1];
    for(Int i=1;i<=n;i++) A[i] = A[i] + A[i-1];
    for(Int i=1;i<=n;i++) sum[i] = sum[i] + A[i-1];
    added = 0; A.clear(); A.resize(n+1);
  }

  //[l, r)にxを加算
  void add(Int l, Int r, T x){
    added = 1;
    assert(l <= r && 0 <= l && r <= n);
    A[l] = A[l] + x;
    A[r] = A[r] - x;
  }

  //[l, r)の和を得る
  T get(Int l,Int r){
    assert(l<=r && 0<=l && r<=n);
    if(added) apply();
    return sum[r] - sum[l];
  }
};


template<typename dtype>
class RMQ{
public :
  struct data{
    bool type; //0 - empty   , 1 - update
    dtype value;
  };

  Int n,n_;
  vector<dtype> dat;
  vector<data> td;
  Int toMax;          //0 -> RangeMin 1->RangeMax;
  dtype initValue; /*範囲外の時に返す値*/

  RMQ(){n=-1;}
  RMQ(Int n_, Int toMax, dtype initValue):n_(n_),toMax(toMax), initValue(initValue){
    n=1;
    while(n<n_)n*=2;
    td.resize(2*n-1,(data){0,initValue});
    dat.resize(2*n-1,initValue);
  }

  inline dtype merge(dtype a, dtype b){return toMax? max(a, b):min(a, b);}


  dtype dfs(Int a,Int b,dtype x,bool flag,Int k,Int l,Int r){
    if(r <= a || b <= l) return flag? dat[k]:initValue;
    if(a <= l && r <= b){
      if(flag == true){
        td[k]=(data){1,x};
        dat[k]=x;
      }
      return dat[k];
    }

    if(td[k].type){
      td[k].type = 0;
      dat[k*2+1] = dat[k*2+2] = td[k].value;
      td[k*2+1] = td[k*2+2] = (data){1,td[k].value};
    }

    dtype vl=dfs(a, b, x, flag, k*2+1, l, (l+r)/2);
    dtype vr=dfs(a, b, x, flag, k*2+2, (l+r)/2, r);
    return flag? (dat[k] = merge(vl, vr)):merge(vl,vr);
  }


  //[a, b)の中でx以下の値を持つ最小の添字
  Int query(Int a,Int b,Int x, Int k,Int l,Int r){
    if(r <= a || b <= l) return 0;
    if(a <= l && r <= b && r - l == 1) return dat[k] <= x? l:0;

    if(td[k].type){
      td[k].type = 0;
      dat[k*2+1] = dat[k*2+2] = td[k].value;
      td[k*2+1] = td[k*2+2] = (data){1,td[k].value};
    }

    if(a <= l && r <= b){
      if(dat[k*2+2] <= x)return query(a, b, x, k*2+2, (l+r)/2, r);
      if(dat[k*2+1] <= x) return query(a, b, x, k*2+1, l, (l+r)/2);
      return 0;
    }
    Int vl=query(a, b, x, k*2+1, l, (l+r)/2);
    Int vr=query(a, b, x, k*2+2, (l+r)/2, r);
    return max(vl, vr);
  }

  Int query(Int l,Int r,Int x){
    assert(l <= r), assert(l <= n && r <= n), assert(l >= 0 && r >= 0);
    return query(l, r, x, 0, 0, n);
  }

  //[l,r)の値をxに変更　update(l,r,x)
  void update(Int l,Int r,dtype x){
    assert(l <= r), assert(l <= n && r <= n), assert(l >= 0 && r >= 0);
    dfs(l, r, x, true, 0, 0, n);
  }

  //[l,r)の最小値を得る　find(l,r);
  dtype get(Int l,Int r){
    assert(l <= r), assert(l <= n && r <= n), assert(l >= 0 && r >= 0);
    return dfs(l, r, initValue , false, 0 , 0 ,n);
  }
};


vector<Int> solve(Int N, vector<Int> D, vector<P> R, vector<P> Q){
  if(R.empty()) return vector<Int>(Q.size(), INF);
  CumulativeSum<Int> sumD(2 * N);
  for(Int i=0;i<2*N;i++) sumD.add(i, i+1, D[i%N]);

  RMQ <Int> seg(N * 2, false, INF);
  vector<Int> Bus(N, INF);

  for(auto p:R){
    Int b, t; tie(b, t) = p;
    Bus[b] = min(Bus[b], t);
  }

  for(Int i=0;i<2*N;i++) seg.update(i, i+1, Bus[i%N]);

  vector<Int> V;
  for(Int i=0;i<N;i++) V.push_back(Bus[i]);
  sort(V.begin(), V.end());
  V.erase(unique(V.begin(), V.end()), V.end());


  auto calcDist = [&](Int from, Int to){
    return from <= to? sumD.get(from, to):sumD.get(from, to + N);
  };

  auto calcTime=[&](Int from, Int to, Int v){
    Int bus = seg.query(0, from + 1 + N, v);
    assert(bus!=INF);
    bus%=N;
    Int waitTime = calcDist(bus, from) * v;
    Int busTime = calcDist(from, to) * v;
    Int time = waitTime + busTime;
    if(Bus[bus] > v) return INF;
    return time;
  };

  auto calcCost=[&](Int from, Int to){
    Int L = 0, R = V.size()-1;//dsfasfasd
    while(L+1 < R){
      Int M = (L + R) / 2;
      Int v1 = V[M];
      Int v2 = V[M+1];
      Int time1 = calcTime(from, to, v1);
      Int time2 = calcTime(from, to, v2);
      if(time1 > time2) L = M;
      else R = M;
    }
    Int a = calcTime(from, to, V[L]);
    Int b = calcTime(from, to, V[R]);
    return min(a, b);
  };

  auto calcCost2=[&](Int from, Int to){
    Int res = INF;
    for(Int v:V) Min(res, calcTime(from, to, v));
    return res;
  };

  vector<Int> res;
  for(auto p:Q){
    Int from, to; tie(from, to) = p;
    //Int cost = calcCost(from, to);
    Int cost2 = calcCost2(from, to);
    //pr(cost, cost2);
    //assert(cost == cost2);
    //res.push_back(cost);
    res.push_back(cost2);
  }
  return res;
}

signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  Int N, M, Q;
  cin>>N>>M>>Q;

  vector<Int> rD(N);
  cin>>rD;
  vector<Int> D = rD;
  reverse(rD.begin(), rD.end());

  vector<P> rR;
  vector<P> R;
  for(Int i=0;i<M;i++){
    char ch;
    Int b, t;
    cin>>ch>>b>>t; b--;
    if(ch == 'R') R.emplace_back(b, t);
    if(ch == 'L') rR.emplace_back((N - b)%N, t);
  }

  vector<P> Query;
  vector<P> rQuery;
  for(Int i=0;i<Q;i++){
    Int x, y;
    cin>>x>>y; x--, y--;
    Query.emplace_back(x, y);
    rQuery.emplace_back((N - x)%N, (N - y)%N);
  }

  vector<Int> ansB = solve(N, rD, rR, rQuery);
  vector<Int> ansA = solve(N, D, R, Query);

  for(Int i=0;i<Q;i++){
    Int ans = min(ansA[i], ansB[i]);
    cout<<ans<<endl;
  }

  return 0;
}
accuracy: 0.22641509433962265
time_ms: 20
memory_kb: 3228
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

template <typename T, bool isMin>
struct LiChao{
  static constexpr T INF = numeric_limits<T>::max()/10;
  struct Line{
    T a,b;
    Line(T a,T b):a(a),b(b){}
    T get(T x){return a*x+b;}
  };

  Int n;
  vector<T> pos;
  vector<Line> dat;
  LiChao(vector<T> &pos):pos(pos){init(pos.size());}

  void init(Int n_){
    n=1;
    while(n<n_) n<<=1;
    while((Int)pos.size()<n)
      pos.emplace_back(T(pos.back()+1));
    dat.assign(2*n,Line(0,-INF));
  }

  void addLine(T a,T b){
    if(isMin) a=-a,b=-b;
    Line x(a,b);
    update(1,0,n-1,x);
  }

  T query(T x){
    Int t=lower_bound(pos.begin(),pos.end(),x)-pos.begin();
    return (isMin?-1:1)*query(1,0,n-1,t);
  }

  inline bool over(Line &a,Line &b,T lb,T ub){
    return a.get(lb)>=b.get(lb)&&a.get(ub)>=b.get(ub);
  }

  void update(Int k,Int l,Int r,Line &x){
    T lb=pos[l],ub=pos[r];
    if(over(dat[k],x,lb,ub)) return;
    if(over(x,dat[k],lb,ub)){
      dat[k]=x;
      return;
    }
    Int c=(l+r)>>1;
    if(dat[k].get(pos[c])<x.get(pos[c])) swap(dat[k],x);
    if(dat[k].get(lb)<=x.get(lb)) update((k<<1)|0,l,c,x);
    else update((k<<1)|1,c+1,r,x);
  }

  T query(Int k,Int l,Int r,Int t){
    T res=dat[k].get(pos[t]);
    if(l==r) return res;
    Int c=(l+r)>>1;
    if(t<=c) return max(res,query((k<<1)|0,l,c,t));
    return max(res,query((k<<1)|1,c+1,r,t));
  }
};
template <typename T, bool isMin>
constexpr T LiChao<T, isMin>::INF;

//INSERT ABOVE HERE
signed main(){
  Int n,m,q;
  cin>>n>>m>>q;

  vector<Int> ds(n);
  for(Int i=0;i<n;i++) cin>>ds[i];
  for(Int i=0;i<n;i++) ds.emplace_back(Int(ds[i]));
  for(Int i=0;i<n;i++) ds.emplace_back(Int(ds[i]));

  vector<Int> sm(n*3+1,0);
  for(Int i=0;i<n*3;i++) sm[i+1]=sm[i]+ds[i];

  vector<char> cs(m);
  vector<Int> bs(m),ts(m);
  for(Int i=0;i<m;i++) cin>>cs[i]>>bs[i]>>ts[i],bs[i]--;

  vector< vector<Int> > G(n*3);
  vector<Int> xs(q),ys(q);
  for(Int i=0;i<q;i++){
    cin>>xs[i]>>ys[i];
    xs[i]--,ys[i]--;
    xs[i]+=n,ys[i]+=n;
    G[xs[i]].emplace_back(i);
  }

  const Int INF = 1e18;
  vector<Int> R(n*3,INF),L(n*3,INF);
  Int exR=0,exL=0;
  for(Int i=0;i<m;i++){
    if(cs[i]=='R'){
      exR=1;
      chmin(R[bs[i]+n*0],ts[i]);
      chmin(R[bs[i]+n*1],ts[i]);
      chmin(R[bs[i]+n*2],ts[i]);
    }
    if(cs[i]=='L'){
      exL=1;
      chmin(L[bs[i]+n*0],ts[i]);
      chmin(L[bs[i]+n*1],ts[i]);
      chmin(L[bs[i]+n*2],ts[i]);
    }
  }

  vector<Int> ans(q,INF);
  // use R
  if(exR){
    LiChao<Int, true> cht(sm);
    for(Int x=0;x<n*2;x++){
      if(R[x]!=INF) cht.addLine(R[x],-R[x]*sm[x]);
      for(Int i:G[x]){
        Int y=ys[i];
        if(x>y) y+=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }
  // use L
  if(exL){
    LiChao<Int, true> cht(sm);
    for(Int x=n*3-1;x>=n;x--){
      if(L[x]!=INF) cht.addLine(-L[x],L[x]*sm[x]);
      for(Int i:G[x]){
        Int y=ys[i];
        if(x<y) y-=n;
        chmin(ans[i],cht.query(sm[y]));
      }
    }
  }

  for(Int i=0;i<q;i++) cout<<ans[i]<<"\n";
  cout<<flush;
  return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 46328
final_rank: 15