Problem:
Problem E:
Water Tank
Mr. Denjiro is a science teacher.

Today he has just received a specially ordered water tank that
will certainly be useful for his innovative experiments on water
flow.
Figure 1: The water tank
The size of the tank is 100cm (Width) * 50cm (Height) * 30cm (Depth)
 (see Figure 1).

For the experiments, he fits several partition boards inside of
the tank parallel to the sideboards.

The width of each board is equal to the depth of the tank, i.e. 30cm.
The height of each board is less than that of the tank, i.e. 50 cm,
and differs one another.

The boards are so thin that he can neglect the thickness in the experiments.
Figure 2: The front view of the tank
The front view of the tank is shown in Figure 2.
There are several faucets above the tank and he turns them on at
    the beginning of his experiment.  The tank is initially empty.
    Your mission is to write a
    computer program to simulate water flow in the tank.
Input
The input consists of multiple data sets.
D
is the number of the data sets.
D
DataSet
1
DataSet
2
...
DataSet
D
The format of each data set 
(
DataSet
d
, 1 <=
d
<=
D
) 
is as follows.
N
B
1
H
1
B
2
H
2
...
B
N
H
N
M
F
1
A
1
F
2
A
2
...
F
M
A
M
L
P
1
T
1
P
2
T
2
...
P
L
T
L
Each line in the data set contains one or two integers.
N
is the number of the boards he sets in the tank .
B
i
and
H
i
are the
x
-position (cm) and the height (cm) 
of the
i
-th board, 
where 1 <=
i
<=
N
.
H
i
s differ from one another.  You may assume the
    following.
0 <
N
< 10 ,
0 <
B
1
<
B
2
< ... <
B
N
< 100 ,
0 <
H
1
< 50 ,
0 <
H
2
< 50 ,
 ..., 0 <
H
N
< 50.
M
is the number of the faucets above the tank .
F
j
and
A
j
are 
the
x
-position (cm) and the amount of water flow (cm
3
/second)
of the
j
-th faucet ,
where 1 <=
j
<=
M
.
There is no faucet just above any boards .
Namely, none of
F
j
is equal to
B
i
.
You may assume the following .
0 <
M
<10 ,
0 <
F
1
<
F
2
< ... 
<
F
M
< 100 ,
0 <
A
1
< 100, 
0 <
A
2
< 100, ...
0 <
A
M
< 100.
L
is the number of observation time and location.
P
k
is the
x
-position (cm) of the
k
-th
observation point.
T
k
is the
k
-th observation time in seconds from the beginning.
None of
P
k
is equal to
B
i
.
You may assume the following .
0 <
L
< 10 ,
0 <
P
1
< 100,
0 <
P
2
< 100, ..., 
0 <
P
L
< 100 ,
0 <
T
1
< 1000000, 
0 <
T
2
< 1000000, 
... ,
0 <
T
L
< 1000000.
Output
For each data set,
your program should output
L
lines each containing 
one real number which represents the height (cm) of the water level specified 
by the
x
-position
P
k
at the time
T
k
.
Each answer may not have an error greater than 0.001.
As long as this condition is satisfied,
you may output any number of digits after the decimal point.
After the water tank is filled to the brim,
the water level at any
P
k
is equal to the
height of the tank, that is, 50 cm.
Sample Input
2
5
15 40
35 20
50 45
70 30
80 10
3
20 3
60 2
65 2
6
40 4100
25 7500
10 18000
90 7000
25 15000
25 22000
5
15 40
35 20
50 45
70 30
80 10
2
60 4
75 1
3
60 6000
75 
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
template<int mod>istream &operator>>(istream &is,static_modint<mod> &a){long long b;is>>b;a=b;return is;}
istream &operator>>(istream &is,modint &a){long long b;cin>>b;a=b;return is;}
#endif
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
#define esper(...) static_cast<void>(0)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define reps(i,a,n) for(int i=(a);i<(n);i++)
#define rep(i,n) reps(i,0,n)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<x<<'\n',static_cast<void>(0)
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
void SOLVE();
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout<<fixed<<setprecision(16);
  #ifdef LOCAL
  clock_t start=clock();
  #endif
  int testcase=1;
  cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
  #ifdef LOCAL
  cerr<<"time:";
  cerr<<(clock()-start)/1000;
  cerr<<"ms\n";
  #endif
}
struct UF{
  vector<int>par;
  UF(int n):par(n,-1){}
  int root(int u){
    if(par[u]<0)return u;
    return par[u]=root(par[u]);
  }
  bool same(int u,int v){return root(u)==root(v);}
  void merge(int u,int v){
    int ru=root(u),rv=root(v);
    if(ru==rv)return;
    if(ru>rv)swap(ru,rv);
    par[ru]+=par[rv];
    par[rv]=ru;
  }
};
void SOLVE(){
  int n;
  cin>>n;
  vector<int>board(101,0);
  rep(i,n){
    int a,b;
    cin>>a>>b;
    board[a]=b;
  }
  board[0]=board[100]=1e9;
  int m;
  cin>>m;
  vector<pair<int,int>>water(m);
  cin>>water;
  int l;
  cin>>l;
  vector<pair<int,int>>sokutei(l);
  cin>>sokutei;
  vector<int>left(100,1e9),right(100,1e9);
  left[0]=0,right[99]=100;
  reps(i,1,100){
    if(board[i])left[i]=i;
    else left[i]=left[i-1];
  }
  for(int i=98;i>=0;i--){
    if(board[i+1])right[i]=i+1;
    else right[i]=right[i+1];
  }
  vector<double>now(100,0);
  UF uf(100);
  rep(i,100){
    if(left[i]!=i)uf.merge(i,i-1);
  }
  auto step=[&](int time)->void {
    for(auto [f,a]:water){
      now[uf.root(f)]+=double(a)*time/(30*(right[uf.root(f)]-left[uf.root(f)]));
    }
  };
  auto eval2=[&](int l,int r)->bool {
    assert(left[l]==l);
    assert(left[r]==r);
    double sum=0;
    int mx=max(board[right[l]],board[left[r]]);
    reps(i,l,r+1)if(uf.root(i)==i){
      sum+=now[i]*(right[i]-left[i]);
      if(i!=l)chmax(mx,board[left[i]]);
      if(i!=r)chmax(mx,board[right[i]]);
    }
    int len=right[r]-left[l];
    sum/=len;
    if(sum<mx)return false;
    if(mx>min(board[left[l]],board[right[r]]))return false;
    // if(sum>min(board[left[l]],board[right[r]])){
    //   vector<int>ar;
    //   reps(i,l,r+1)if(uf.root(i)==i)ar.push_back(i);
    //   reps(i,1,ar.size())uf.merge(ar[i],ar[i-1]);
    //   right[l]=right[r];
    //   now[l]=sum;
    //   return true;
    vector<int>ar;
    reps(i,l,r+1)if(uf.root(i)==i)ar.push_back(i);
    reps(i,1,ar.size())uf.merge(ar[i],ar[i-1]);
    right[l]=right[r];
    now[l]=sum;
    return true;
  };
  auto eval=[&]()->void {
    vector<int>ar;
    rep(fh,120){
      rep(i,100)if(uf.root(i)==i){
        ar.push_back(i);
      }
      assert(!ar.empty()&&ar.size()<=11);
      vector<bool>connected(ar.size(),false);
      rep(i,ar.size())reps(j,i+1,ar.size()){
        bool ok=true;
        reps(k,i,j+1)ok&=!connected[k];
        if(ok){
          if(eval2(ar[i],ar[j]))reps(k,i,j+1)connected[k]=true;
        }
      }
      debug(fh);
      ar.clear();
    }
    rep(i,100)if(uf.root(i)==i)ar.push_back(i);
    // vector<bool>seen(ar.size(),false);
    rep(j,ar.size())debug(ar[j],now[ar[j]]);
    rep(j,120){
      double mx=0;
      int i=-1;
      ar.clear();
      rep(k,100)if(uf.root(k)==k)ar.push_back(k);
      debug(ar);
      rep(k,ar.size())if(uf.root(ar[k])==ar[k]&&min(board[left[ar[k]]],board[right[ar[k]]])<now[ar[k]]){
        i=k;
        break;
      }
      if(i==-1)break;
      // debug(i,ar[i],now[ar[i]]);
      // if(min(board[left[ar[i]]],board[right[ar[i]]])>=now[ar[i]]){
      //   seen[i]=true;
      //   continue;
      // }
      if(board[left[ar[i]]]<board[right[ar[i]]]){
        double over=(now[ar[i]]-board[left[ar[i]]])*(right[ar[i]]-left[ar[i]]);
        now[ar[i-1]]+=over/(right[ar[i-1]]-left[ar[i-1]]);
        now[ar[i]]=board[left[ar[i]]];
      }
      else{
        double over=(now[ar[i]]-board[right[ar[i]]])*(right[ar[i]]-left[ar[i]]);
        now[ar[i+1]]+=over/(right[ar[i+1]]-left[ar[i+1]]);
        now[ar[i]]=board[right[ar[i]]];
      }
      vector<int>ar2;
      rep(i,100)if(uf.root(i)==i){
        ar2.push_back(i);
      }
      // assert(!ar.empty()&&ar.size()<=11);
      vector<bool>connected(ar2.size(),false);
      rep(i,ar2.size())reps(j,i+1,ar2.size()){
        bool ok=true;
        reps(k,i,j+1)ok&=!connected[k];
        if(ok){
          if(eval2(ar2[i],ar2[j]))reps(k,i,j+1)connected[k]=true;
        }
      }
      // seen[i]=true;
    }
  };
  vector<int>ord(l);
  iota(all(ord),0);
  sort(all(ord),[&](int x,int y){return sokutei[x].second<sokutei[y].second;});
  vector<double>ans(l,-1);
  int pre=0;
  for(int i:ord){
    step(sokutei[i].second-pre);
    rep(j,100)if(uf.root(j)==j)debug(j,now[j]);
    eval();
    rep(j,100)if(uf.root(j)==j)debug(j,now[j]);
    pre=sokutei[i].second;
    ans[i]=min<double>(50,now[uf.root(sokutei[i].first)]);
  }
  rep(i,l)cout<<ans[i]<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3508
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using pii = pair<int,int>;
using ll = long long;
#define rep(i, j) for(int i=0; i < (int)(j); i++)
#define all(v) v.begin(),v.end()
const double EPS = 1e-8;

struct Node {
    int l, r, h;
    double water;
    bool is_child_full;
    list<Node> children; // all children shold have same height.
    Node(int l, int r, int h) : l(l), r(r), h(h), water(0), is_child_full(false) {}    
    void insert(int b, int h, int d = 0) {
        if(children.size() == 0) {
            children.push_back(Node(l, b, h));
            children.push_back(Node(b, r, h));
        } else {
            auto child = find(b);
            if(child->h != h) {
                child->insert(b, h, d+1);
            } else {
                int lc = child->l;
                child->l = b;
                children.insert(child, Node(lc, b, h));
            }
        }
    }
    // find child which range contains p
    list<Node>::iterator find(int p) {
        for(auto c = begin(children); c != end(children); c++) {
            if(c->l <= p and p < c->r) return c;
        }
        assert(0);
    }
    double capacity() {
        return 30.0 * h * (r - l);
    }
    double pour(int p, double a) {
        if(water + a >= capacity()) {
            double left = water + a - capacity();
            water = capacity();
            return left;
        }
        water += a;
        assert(water / 30.0 / (r - l) <= h);
        if(children.size() > 0) {
            auto child = find(p);
            double left = child->pour(p, a);
            if(left == 0) return 0;
            assert(abs(child->height(p) - child->h) < EPS); // child is full
            double left1 = left / 2, left2 = left / 2;
            // go right
            auto c2 = child;
            while(left1 > 0 and c2 != end(children)) {
                left1 = c2->pour(c2->l, left1);
                c2++;
            }
            // go left
            c2 = child;            
            left2 += left1;
            if(c2 != begin(children)) {
                do {
                    c2--;
                    left2 = c2->pour(c2->r - 1, left2);
                } while(left2 > 0 and c2 != begin(children));
            }
            // go right(2nd)
            c2 = child;
            while(left2 > 0 and c2 != end(children)) {
                left2 = c2->pour(c2->l, left2);
                c2++;
            }
            if(left2 > 0) is_child_full = true;
        }
        return 0;
    }
    double height(int p) {
        if(is_child_full or children.size() == 0) return water / 30.0 / (r - l);
        return find(p)->height(p);
    }
    void show_structure(int d = 0) {        
        if(is_child_full) return;
        rep(i, d) cerr << "\t";
        for(auto p : children) cerr << "[" << p.l << ", " << p.water / 30.0 / (p.r - p.l) << "/" << p.h << " , " << p.r << ")" << " ";
        cerr << endl;
        for(auto p : children) p.show_structure(d + 1);
    }
};


void solve() {
    int N; cin >> N;
    // make tree
    vector<pii> HB(N); rep(i, N) cin >> HB[i].second >> HB[i].first;
    sort(all(HB), greater<pii>());    
    Node root(0, 100, 50);
    rep(i, N) root.insert(HB[i].second, HB[i].first);
    //root.show_structure();
    
    // input pour
    int M; cin >> M;
    vector<int> F(M), A(M); rep(i, M) cin >> F[i] >> A[i];
    // input measure
    int L; cin >> L;
    vector<pair<pii,int>> TP(L);
    rep(i, L) {
        cin >> TP[i].first.second >> TP[i].first.first;
        TP[i].second = i;
    }
    sort(all(TP));

    // simulate for each t    
    int tp_i = 0;
    vector<double> ans(L, -1);
    rep(t, 1000000) {
        // measure point
        while(tp_i < L and TP[tp_i].first.first == t) {            
            double a = root.height(TP[tp_i].first.second);
            ans[TP[tp_i].second] = a;
            tp_i++;
        }
        // update height
        rep(m, M) root.pour(F[m], A[m]);
    }
    rep(i, L) printf("%.6lf\n", ans[i]);
}


int main() {
    int D; cin >> D;
    rep(i, D) solve();
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3180
final_rank: 7

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

using pii = pair<int,int>;
using ll = long long;
#define rep(i, j) for(int i=0; i < (int)(j); i++)
#define all(v) v.begin(),v.end()
#define debug(x) cerr << #x << " : " << x << endl
// vector
template<class T> istream& operator >> (istream &is , vector<T> &v) { for(T &a : v) is >> a; return is; }

const double EPS = 1e-8;

struct Node {
    int l, r, h;
    double water;
    bool is_child_full;
    list<Node> children;
    Node(int l, int r, int h) : l(l), r(r), h(h), water(0), is_child_full(false) {}
    void insert(int b, int h, int d = 0) {
        if(children.size() == 0) {
            children.push_back(Node(l, b, h));
            children.push_back(Node(b, r, h));
        } else {
            auto child = find(b);
            if(child->h != h) {
                child->insert(b, h, d+1);
            } else {
                int lc = child->l;
                child->l = b;
                children.insert(child, Node(lc, b, h));
            }
        }
    }
    list<Node>::iterator find(int p) {
        for(auto c = begin(children); c != end(children); c++) {
            if(c->l <= p and p < c->r) return c;
        }
        assert(0);
    }
    double capacity() {
        return 30.0 * h * (r - l);
    }
    double pour(int p, double a) {
        if(water + a >= capacity()) {
            double left = water + a - capacity();
            water = capacity();
            return left;
        }
        water += a;
        assert(water / 30.0 / (r - l) <= h);
        if(children.size() > 0) {
            auto child = find(p);
            double left = child->pour(p, a);
            if(left == 0) return 0;
            assert(abs(child->height(p) - child->h) < EPS); // child is full
            double left1 = left / 2, left2 = left / 2;
            // go right
            auto c2 = child;
            while(left1 > 0 and c2 != end(children)) {
                left1 = c2->pour(c2->l, left1);
                c2++;
            }
            // go left
            c2 = child;            
            left2 += left1;
            if(c2 != begin(children)) {
                do {
                    c2--;
                    left2 = c2->pour(c2->r - 1, left2);
                } while(left2 > 0 and c2 != begin(children));
            }
            // go right(2nd)
            c2 = child;
            while(left2 > 0 and c2 != end(children)) {
                left2 = c2->pour(c2->l, left2);
                c2++;
            }
            if(left2 > 0) is_child_full = true;
        }
        return 0;
    }
    double height(int p) {
        if(is_child_full or children.size() == 0) return water / 30.0 / (r - l);
        return find(p)->height(p);
    }
    void show_structure(int d = 0) {
        rep(i, d) cerr << "\t";        
        if(is_child_full) {
            cerr << water / 30.0 / (r - l) << " / " << h << " (child full)" << endl;
            return;
        }
        
        for(auto p : children) {            
            cerr << "[" << p.l << ", " << p.water / 30.0 / (p.r - p.l) << "/" << p.h << " , " << p.r << ")" << " ";
        }
        cerr << endl;
        for(auto p : children) p.show_structure(d + 1);
    }
};


void solve() {
    int N; cin >> N;
    vector<pii> HB(N); rep(i, N) cin >> HB[i].second >> HB[i].first;
    sort(all(HB), greater<pii>());
    
    Node root(0, 100, 50);
    rep(i, N) root.insert(HB[i].second, HB[i].first);
    
    int M; cin >> M;
    vector<int> F(M), A(M); rep(i, M) cin >> F[i] >> A[i];
    
    int L; cin >> L;
    vector<pair<pii,int>> TP(L);
    rep(i, L) {
        cin >> TP[i].first.second >> TP[i].first.first;
        TP[i].second = i;
    }
    //root.show_structure();
    sort(all(TP));
    int tp_i = 0;
    vector<double> ans(L, -1);
    rep(t, 1000000) {
        while(tp_i < L and TP[tp_i].first.first == t) {
            double a = root.height(TP[tp_i].first.second);
            ans[TP[tp_i].second] = a;
            tp_i++;
        }
        rep(m, M) {
            root.pour(F[m], A[m]);
        }
    }
    rep(i, L) printf("%.6lf\n", ans[i]);
}


int main() {
    int D; cin >> D;
    rep(i, D) solve();
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3160
final_rank: 6

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

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf=1e9;
const int64_t inf64=1e18;
const double eps=1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
    os << "[";
    for (const auto &v : vec) {
    	os << v << ",";
    }
    os << "]";
    return os;
}

struct node{
    int left_pos,right_pos,left_height,right_height;
    double sum,flow;
};

void solve(){
    int n;
    cin >> n;
    vector<int> b(n+2),h(n+2); //???????????????
    b[0]=0;
    b[n+1]=100;
    h[0]=50;
    h[n+1]=50;
    rep(i,1,n+1) cin >> b[i] >> h[i];
    int m;
    cin >> m;
    vector<int> f(m),a(m); //???????????????
    rep(i,0,m) cin >> f[i] >> a[i];
    int l;
    cin >> l;
    vector<int> p(l),t(l); //???????????????
    vector<vector<int>> query(1000000);
    rep(i,0,l){
        cin >> p[i] >> t[i];
        query[t[i]].push_back(i);
    }

    list<node> intervals;
    rep(i,0,n+1){
        node n;
        n.left_pos=b[i];
        n.right_pos=b[i+1];
        n.left_height=h[i];
        n.right_height=h[i+1];
        n.sum=n.flow=0;
        rep(j,0,m){
            if(f[j]<n.left_pos or n.right_pos<f[j]) continue;
            n.flow+=a[j];
        }
        intervals.push_back(n);
    }
    vector<double> ans(l);
    rep(ct,1,1000000){
        for(auto &interval:intervals) interval.sum+=interval.flow;
        for(;;){
            bool update=false;
            for(auto it=intervals.begin();; ++it){
                auto left=it,right=it;
                ++right;
                if(min({left->left_height,left->right_height})==min({right->left_height,right->right_height}) and
                   left->sum+right->sum>=30*(right->right_pos-left->left_pos)*left->right_height){
                       node n=*left;
                       n.right_pos=right->right_pos;
                       n.right_height=right->right_height;
                       n.sum+=right->sum;
                       n.flow+=right->flow;
                       auto tmp=intervals.insert(left,n);
                       ++tmp;
                       tmp=intervals.erase(tmp);
                       intervals.erase(tmp);

                       update=true;
                       break;
                }
                if(right->right_height==50) break;
            }

            for(auto it=intervals.begin(); it!=intervals.end(); ++it){
                auto &interval=*it;
                double s=30*(interval.right_pos-interval.left_pos);
                if(interval.left_height<interval.right_height){
                    double h=interval.sum/s;
                    if(h>interval.left_height){
                        double d=h-interval.left_height;
                        interval.sum-=d*s;
                        auto left=it;
                        --left;
                        left->sum+=d*s;

                        update=true;
                    }
                }else{
                    double h=interval.sum/s;
                    if(h>interval.right_height){
                        double d=h-interval.right_height;
                        interval.sum-=d*s;
                        auto right=it;
                        ++right;
                        right->sum+=d*s;

                        update=true;
                    }
                }
            }
            if(!update or intervals.size()==1) break;
        }
        for(int i:query[ct]){
            for(auto interval:intervals){
                if(p[i]<interval.left_pos or interval.right_pos<p[i]) continue;
                ans[i]=min(50.,interval.sum/30/(interval.right_pos-interval.left_pos));
                break;
            }
        }
    }
    rep(i,0,l) cout << ans[i] << endl;
}

int main(){
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    cout.setf(ios::fixed);
    cout.precision(10);
    int d;
    cin >> d;
    rep(i,0,d) solve();
    return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 26624
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
#define D10 fixed<<setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 114514810;
const int MOD = 1000000007;
const double EPS = 1e-10;
typedef double weight;
struct edge
{
	int to; weight cost;
	bool operator < (const edge& e) const { return cost < e.cost; }
	bool operator >(const edge& e) const { return cost > e.cost; }
};

typedef vector<edge> Edges;
typedef vector<Edges> Graph;
//int dx[] = { -1, 0, 0, 1 }; int dy[] = { 0, -1, 1, 0 };
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
bool valid(int x, int y, int h, int w) { return (x >= 0 && y >= 0 && x < h&&y < w); }
int place(int x, int y, int w) { return w*x + y; }
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

typedef pair<int, double> pid;
struct data{ int lx, rx, lh, rh; double h; };
vector<data> v;

double add(int p, double w)
{
	REP(i, v.size())
	{
		if (v[i].lx <= p && v[i].rx>=p)
		{
			double bot = (v[i].rx - v[i].lx + 1) * 30;
			int minh = min(v[i].rh, v[i].lh);
			if (v[i].h - minh > -EPS)
			{
				if (v[i].h - v[i].lh > -EPS)
				{
					if (abs(v[i-1].h - v[i].h) < EPS) return w;
					else add(v[i - 1].lx, w);
				}
				else
				{
					if (abs(v[i + 1].h - v[i].h) < EPS) return w;
					else add(v[i + 1].lx, w);
				}
			}
			else
			{
				if ((minh - v[i].h)*bot - w > -EPS)
				{
					v[i].h += w / bot;
					return 0;
				}
				else
				{
					double rt = w - (minh - v[i].h)*bot;
					v[i].h = minh;
					return rt;
				}
			}
		}
	}
}

int main()
{
	int D;
	cin >> D;
	while (D--)
	{
		v.clear();
		int n, m, l;
		vector<pid> s;
		vector<pii> b, q;
		cin >> n;
		REP(i, n)
		{
			int x, y;
			cin >> x >> y;
			b.push_back(pii(x, y));
		}		
		cin >> m;
		REP(i, m)
		{
			int x, y;
			cin >> x >> y;
			s.push_back(pii(x, y));
		}
		cin >> l;
		REP(i, l)
		{
			int x, y;
			cin >> x >> y;
			q.push_back(pii(x, y));
		}

		v.push_back(data{ 0, b[0].first - 1, INF, b[0].second, 0 });
		REP(i, n - 1) v.push_back(data{ b[i].first, b[i + 1].first - 1, b[i].second, b[i + 1].second, 0 });
		v.push_back(data{ b.back().first, 99, b.back().second, INF, 0 });

		vector<bool> f(l); vector<double> ans(l);
		REP(i, l)
		{
			if (q[i].second >= 150000)
			{
				ans[i] = 50;
				f[i] = true;
			}
		}

		for (int time = 1;time<=150000; time++)
		{
			vector<pid> res = s;
			while (res.size())
			{
				vector<pid> nres;
				REP(i, res.size())
				{
					double d = add(res[i].first, res[i].second);
					if (d > EPS) nres.push_back(pid(res[i].first, d));
				}
				res = nres;

				vector<data> nv;
				REP(i, v.size())
				{
					if (i<v.size()-1 && v[i].h - v[i].rh > -EPS&&v[i+1].h - v[i+1].lh > -EPS)
					{
						nv.push_back(data{ v[i].lx, v[i + 1].rx, v[i].lh, v[i + 1].rh, v[i].h });
						i++;
					}
					else nv.push_back(v[i]);
				}
				v = nv;
			}

			bool end = true;
			REP(i, l)
			{
				if (q[i].second == time)
				{
					REP(j, v.size())
					{
						if (q[i].first >= v[j].lx&&q[i].first <= v[j].rx) 
							ans[i] = min(v[j].h, 50.0);
					}
					f[i] = true;
				}
				if (!f[i]) end = false;
			}
			if (end) break;
		}
		REP(i, l) cout << D10 << ans[i] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1284
final_rank: 3

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

class Cell {
public:
  int parent;
  int brother;
  bool has_child;

  int water;
  int capacity;
  int height;
  int start_x;
  int end_x;
  Cell(int _h,int _sx,int _ex) : height(_h),start_x(_sx),end_x(_ex),
				 parent(-1),brother(-1),water(0),has_child(false){
    capacity = height * (end_x - start_x) * 30;
  }

  void pour_water(int _water){
    water += _water;
  }

  double compute_water_level(){
    return (double)water / ((double)(end_x - start_x) * 30.0);
  }
  bool is_filled(){
    return (capacity <= water);
  }

  bool operator<(const Cell& c) const{
    return start_x < c.start_x;
  }
  bool operator<(const int _x) const{
    return start_x < _x;
  }
};

struct Board{
  int x;
  int height;
  Board(int _x,int _h) : x(_x), height(_h) {}
  bool operator<(const Board& b) const{
    return x < b.x;
  }
  bool operator>(const Board& b) const{
    return x > b.x;
  }
};

struct Faucet{
  int x;
  int cm3_per_second;
  Faucet(int _x,int _c) : x(_x), cm3_per_second(_c) {}
  Faucet() : x(0), cm3_per_second(0) {}

  bool operator <(const Faucet& f) const{
    return (x < f.x);
  }

  bool operator >(const Faucet& f) const{
    return (x > f.x);
  }
  bool operator ==(const Faucet& f) const{
    return (x == f.x);
  }

  bool operator <(const int _x) const{
    return (x < _x);
  }
  bool operator >(const int _x) const{
    return (x > _x);
  }
  bool operator ==(const int _x) const{
    return (x == _x);
  }
};

int main(){
  int total_data_sets;
  while(~scanf("%d",&total_data_sets)){
    for(int data_set_idx = 0; data_set_idx < total_data_sets; data_set_idx++){

      vector<Cell> cells;
      vector<Board> boards;
      int total_boards;
      scanf("%d",&total_boards);

      boards.push_back(Board(0,50));
      for(int board_idx = 0; board_idx < total_boards; board_idx++){
	int x,height;
	scanf("%d %d",&x,&height);
	boards.push_back(Board(x,height));
      }
      boards.push_back(Board(100,50));

      sort(boards.begin(),boards.end());
      for(int src_idx = 0; src_idx < boards.size(); src_idx++){
	if(boards[src_idx].x == 100) continue;

	for(int target_idx = src_idx+1; target_idx < boards.size(); target_idx++){
	  if(boards[target_idx].height < boards[src_idx].height) continue;

	  else if(boards[target_idx].height >= boards[src_idx].height){
	    cells.push_back(Cell(boards[src_idx].height,boards[src_idx].x,boards[target_idx].x));
	    break;
	  }
	}

	for(int target_idx = src_idx-1; target_idx >= 0; target_idx--){
	  if(boards[target_idx].height < boards[src_idx].height) continue;

	  else if(boards[target_idx].height > boards[src_idx].height){
	    cells.push_back(Cell(boards[src_idx].height,boards[target_idx].x,boards[src_idx].x));
	    break;
	  }
	}
      }

      //set brother
      for(int src_idx=0;src_idx<cells.size();src_idx++){
	int height = cells[src_idx].height;

	int target_wall[101];
	memset(target_wall,0,sizeof(target_wall));

	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(target_idx == src_idx) continue;

	  if(cells[src_idx].end_x == cells[target_idx].start_x){
	    target_wall[cells[target_idx].start_x] = max(cells[target_idx].height,target_wall[cells[target_idx].start_x]);
	  }
	  if(cells[src_idx].start_x == cells[target_idx].end_x){
	    target_wall[cells[target_idx].end_x] = max(cells[target_idx].height,target_wall[cells[target_idx].end_x]);
	  }
	}

	int diff = INF;
	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(src_idx == target_idx) continue;
	  if(cells[src_idx].end_x == cells[target_idx].start_x
	     && height == target_wall[cells[target_idx].start_x]
	     && diff > abs(cells[src_idx].end_x - cells[target_idx].end_x)){
	    diff = abs(cells[src_idx].end_x - cells[target_idx].end_x);
	    cells[src_idx].brother = target_idx;
	  }
	  if(cells[src_idx].start_x == cells[target_idx].end_x
	     && height == target_wall[cells[target_idx].end_x]
	     && diff > abs(cells[src_idx].start_x - cells[target_idx].start_x)){
	    diff = abs(cells[src_idx].start_x - cells[target_idx].start_x);
	    cells[src_idx].brother = target_idx;
	  }
	}
      }

      //set parent
      for(int src_idx=0;src_idx<cells.size();src_idx++){
	int min_height = INF;
	int lower_height = cells[src_idx].height;
	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(src_idx == target_idx) continue;

	  if(cells[src_idx].start_x >= cells[target_idx].start_x
	     && cells[src_idx].end_x <= cells[target_idx].end_x
	     && lower_height <= cells[target_idx].height
	     && min_height > cells[target_idx].height){
	    min_height = cells[target_idx].height;
	    cells[src_idx].parent = target_idx;
	  }
	}

	if(cells[src_idx].parent != -1){
	  cells[cells[src_idx].parent].has_child = true;
	}
      }


      vector<Faucet> faucets;
      int total_faucets;
      scanf("%d",&total_faucets);
      for(int foucet_idx = 0; foucet_idx < total_faucets; foucet_idx++){
	int x,cm3_per_second;
	scanf("%d %d",&x,&cm3_per_second);
	faucets.push_back(Faucet(x,cm3_per_second));
      }

      sort(faucets.begin(),faucets.end());


      int total_observation_times;
      scanf("%d",&total_observation_times);

      vector<Cell> store = cells;
      for(int observation_time_idx = 0; observation_time_idx < total_observation_times; observation_time_idx++){
	int x,time;
	scanf("%d %d",&x,&time);
	
	for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	  for(int faucet_idx = 0; faucet_idx < faucets.size();faucet_idx++){
	    if(faucet_idx == faucets.size()) continue;
	    if(faucets[faucet_idx].x < cells[cell_idx].start_x) continue;
	    if(faucets[faucet_idx].x > cells[cell_idx].end_x) continue;
	    if(cells[cell_idx].has_child) continue;
	    
	    cells[cell_idx].pour_water(faucets[faucet_idx].cm3_per_second * time);
	  }
	}


	bool is_erased[1001];
	memset(is_erased,false,sizeof(is_erased));

	bool is_updated = false;
	for(int round=0;round<1000;round++){
	  for(int src_idx = 0;src_idx < cells.size(); src_idx++){
	    if(is_erased[src_idx]) continue;
	    if(!cells[src_idx].is_filled()) continue;

	    int freq[1001];
	    memset(freq,0,sizeof(freq));

	    int limit = cells.size() * 3;
	    int cell_idx = src_idx;

	    bool isok = true;
	    while(limit-- > 0){
	      if(!cells[cell_idx].is_filled()) break;

	      freq[cell_idx]++;
	      if(freq[cell_idx] >= 3) isok = false;
	      int brother = cells[cell_idx].brother;
	      if(brother == -1) break;
	      cells[brother].water += (cells[cell_idx].water - cells[cell_idx].capacity);
	      cells[cell_idx].water = cells[cell_idx].capacity;
	      cell_idx = brother;
	    }
	    
	    if(isok) continue;

	    is_updated = true;
	    int sx = INF;
	    int ex = 0;
	    int water = 0;

	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;

	      if(freq[cell_idx] >= 3){
		sx = min(sx,cells[cell_idx].start_x);
		ex = max(ex,cells[cell_idx].end_x);
		water += cells[cell_idx].water;
		cells[cell_idx].water = 0;
		is_erased[cell_idx] = true;
	      }
	    }
	    
	    int new_cell_idx = 0;
	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;
	      
	      if(sx == cells[cell_idx].start_x 
		 && ex == cells[cell_idx].end_x){

		cells[cell_idx].water = water;
		new_cell_idx = cell_idx;

		break;
	      }
	    }
	    
	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;
	      if(cells[cell_idx].brother != -1
		 &&is_erased[cells[cell_idx].brother]){
		cells[cell_idx].brother = new_cell_idx;
	      }
	    }
	  }

	  if(!is_updated) break;
	}

	double res= 0.0;
	for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	  if(cells[cell_idx].start_x <= x && x <= cells[cell_idx].end_x){
	    res = max(cells[cell_idx].compute_water_level(),res);
	  }
	}
	printf("%lf\n",res >= 50.0 ? 50.0 : res);
	cells = store;
      }
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1228
final_rank: 1

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

class Cell {
public:
  int parent;
  int brother;
  bool has_child;

  int water;
  int capacity;
  int height;
  int start_x;
  int end_x;
  Cell(int _h,int _sx,int _ex) : height(_h),start_x(_sx),end_x(_ex),
				 parent(-1),brother(-1),water(0),has_child(false){
    capacity = height * (end_x - start_x) * 30;
  }

  void pour_water(int _water){
    water += _water;
  }

  double compute_water_level(){
    return (double)water / ((double)(end_x - start_x) * 30.0);
  }
  bool is_filled(){
    return (capacity <= water);
  }

  bool operator<(const Cell& c) const{
    return start_x < c.start_x;
  }
  bool operator<(const int _x) const{
    return start_x < _x;
  }
};

struct Board{
  int x;
  int height;
  Board(int _x,int _h) : x(_x), height(_h) {}
  bool operator<(const Board& b) const{
    return x < b.x;
  }
  bool operator>(const Board& b) const{
    return x > b.x;
  }
};

struct Faucet{
  int x;
  int cm3_per_second;
  Faucet(int _x,int _c) : x(_x), cm3_per_second(_c) {}
  Faucet() : x(0), cm3_per_second(0) {}

  bool operator <(const Faucet& f) const{
    return (x < f.x);
  }

  bool operator >(const Faucet& f) const{
    return (x > f.x);
  }
  bool operator ==(const Faucet& f) const{
    return (x == f.x);
  }

  bool operator <(const int _x) const{
    return (x < _x);
  }
  bool operator >(const int _x) const{
    return (x > _x);
  }
  bool operator ==(const int _x) const{
    return (x == _x);
  }
};

int main(){
  int total_data_sets;
  while(~scanf("%d",&total_data_sets)){
    for(int data_set_idx = 0; data_set_idx < total_data_sets; data_set_idx++){

      vector<Cell> cells;
      vector<Board> boards;
      int total_boards;
      scanf("%d",&total_boards);

      boards.push_back(Board(0,50));
      for(int board_idx = 0; board_idx < total_boards; board_idx++){
	int x,height;
	scanf("%d %d",&x,&height);
	boards.push_back(Board(x,height));
      }
      boards.push_back(Board(100,50));

      sort(boards.begin(),boards.end());
      for(int src_idx = 0; src_idx < boards.size(); src_idx++){
	if(boards[src_idx].x == 100) continue;

	for(int target_idx = src_idx+1; target_idx < boards.size(); target_idx++){
	  if(boards[target_idx].height < boards[src_idx].height) continue;

	  else if(boards[target_idx].height >= boards[src_idx].height){
	    cells.push_back(Cell(boards[src_idx].height,boards[src_idx].x,boards[target_idx].x));
	    break;
	  }
	}

	for(int target_idx = src_idx-1; target_idx >= 0; target_idx--){
	  if(boards[target_idx].height < boards[src_idx].height) continue;

	  else if(boards[target_idx].height > boards[src_idx].height){
	    cells.push_back(Cell(boards[src_idx].height,boards[target_idx].x,boards[src_idx].x));
	    break;
	  }
	}
      }

      //set brother
      for(int src_idx=0;src_idx<cells.size();src_idx++){
	int height = cells[src_idx].height;

	int target_wall[101];
	memset(target_wall,0,sizeof(target_wall));

	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(target_idx == src_idx) continue;

	  if(cells[src_idx].end_x == cells[target_idx].start_x){
	    target_wall[cells[target_idx].start_x] = max(cells[target_idx].height,target_wall[cells[target_idx].start_x]);
	  }
	  if(cells[src_idx].start_x == cells[target_idx].end_x){
	    target_wall[cells[target_idx].end_x] = max(cells[target_idx].height,target_wall[cells[target_idx].end_x]);
	  }
	}

	int diff = INF;
	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(src_idx == target_idx) continue;
	  if(cells[src_idx].end_x == cells[target_idx].start_x
	     && height == target_wall[cells[target_idx].start_x]
	     && diff > abs(cells[src_idx].end_x - cells[target_idx].end_x)){
	    diff = abs(cells[src_idx].end_x - cells[target_idx].end_x);
	    cells[src_idx].brother = target_idx;
	  }
	  if(cells[src_idx].start_x == cells[target_idx].end_x
	     && height == target_wall[cells[target_idx].end_x]
	     && diff > abs(cells[src_idx].start_x - cells[target_idx].start_x)){
	    diff = abs(cells[src_idx].start_x - cells[target_idx].start_x);
	    cells[src_idx].brother = target_idx;
	  }
	}
      }

      //set parent
      for(int src_idx=0;src_idx<cells.size();src_idx++){
	int min_height = INF;
	int lower_height = cells[src_idx].height;
	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(src_idx == target_idx) continue;

	  if(cells[src_idx].start_x >= cells[target_idx].start_x
	     && cells[src_idx].end_x <= cells[target_idx].end_x
	     && lower_height <= cells[target_idx].height
	     && min_height > cells[target_idx].height){
	    min_height = cells[target_idx].height;
	    cells[src_idx].parent = target_idx;
	  }
	}

	if(cells[src_idx].parent != -1){
	  cells[cells[src_idx].parent].has_child = true;
	}
      }


      vector<Faucet> faucets;
      int total_faucets;
      scanf("%d",&total_faucets);
      for(int foucet_idx = 0; foucet_idx < total_faucets; foucet_idx++){
	int x,cm3_per_second;
	scanf("%d %d",&x,&cm3_per_second);
	faucets.push_back(Faucet(x,cm3_per_second));
      }

      sort(faucets.begin(),faucets.end());


      int total_observation_times;
      scanf("%d",&total_observation_times);

      vector<Cell> store = cells;
      for(int observation_time_idx = 0; observation_time_idx < total_observation_times; observation_time_idx++){
	int x,time;
	scanf("%d %d",&x,&time);
	
	for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	  for(int faucet_idx = 0; faucet_idx < faucets.size();faucet_idx++){
	    if(faucet_idx == faucets.size()) continue;
	    if(faucets[faucet_idx].x < cells[cell_idx].start_x) continue;
	    if(faucets[faucet_idx].x > cells[cell_idx].end_x) continue;
	    if(cells[cell_idx].has_child) continue;
	    
	    cells[cell_idx].pour_water(faucets[faucet_idx].cm3_per_second * time);
	  }
	}


	bool is_erased[1001];
	memset(is_erased,false,sizeof(is_erased));

	for(int round=0;round<1000;round++){
	  for(int src_idx = 0;src_idx < cells.size(); src_idx++){
	    if(is_erased[src_idx]) continue;
	    if(!cells[src_idx].is_filled()) continue;

	    int freq[1001];
	    memset(freq,0,sizeof(freq));

	    int limit = cells.size() * 3;
	    int cell_idx = src_idx;

	    bool isok = true;
	    while(limit-- > 0){
	      if(!cells[cell_idx].is_filled()) break;

	      freq[cell_idx]++;
	      if(freq[cell_idx] >= 3) isok = false;
	      int brother = cells[cell_idx].brother;
	      if(brother == -1) break;
	      cells[brother].water += (cells[cell_idx].water - cells[cell_idx].capacity);
	      cells[cell_idx].water = cells[cell_idx].capacity;
	      cell_idx = brother;
	    }
	    
	    if(isok) continue;

	    int sx = INF;
	    int ex = 0;
	    int water = 0;

	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;

	      if(freq[cell_idx] >= 3){
		sx = min(sx,cells[cell_idx].start_x);
		ex = max(ex,cells[cell_idx].end_x);
		water += cells[cell_idx].water;
		cells[cell_idx].water = 0;
		is_erased[cell_idx] = true;
	      }
	    }
	    
	    int new_cell_idx = 0;
	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;
	      
	      if(sx == cells[cell_idx].start_x 
		 && ex == cells[cell_idx].end_x){

		cells[cell_idx].water = water;
		new_cell_idx = cell_idx;

		break;
	      }
	    }
	    
	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;
	      if(cells[cell_idx].brother != -1
		 &&is_erased[cells[cell_idx].brother]){
		cells[cell_idx].brother = new_cell_idx;
	      }
	    }
	  }
	}

	double res= 0.0;
	for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	  if(cells[cell_idx].start_x <= x && x <= cells[cell_idx].end_x){
	    res = max(cells[cell_idx].compute_water_level(),res);
	  }
	}
	printf("%lf\n",res >= 50.0 ? 50.0 : res);
	cells = store;
      }
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1228
final_rank: 1

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

class Cell {
public:
  int parent;
  int brother;
  bool has_child;

  int water;
  int capacity;
  int height;
  int start_x;
  int end_x;
  Cell(int _h,int _sx,int _ex) : height(_h),start_x(_sx),end_x(_ex),
				 parent(-1),brother(-1),water(0),has_child(false){
    capacity = height * (end_x - start_x) * 30;
  }

  void pour_water(int _water){
    water += _water;
  }

  double compute_water_level(){
    return (double)water / ((double)(end_x - start_x) * 30.0);
  }
  bool is_filled(){
    return (capacity <= water);
  }

  bool operator<(const Cell& c) const{
    return start_x < c.start_x;
  }
  bool operator<(const int _x) const{
    return start_x < _x;
  }
};

struct Board{
  int x;
  int height;
  Board(int _x,int _h) : x(_x), height(_h) {}
  bool operator<(const Board& b) const{
    return x < b.x;
  }
  bool operator>(const Board& b) const{
    return x > b.x;
  }
};

struct Faucet{
  int x;
  int cm3_per_second;
  Faucet(int _x,int _c) : x(_x), cm3_per_second(_c) {}
  Faucet() : x(0), cm3_per_second(0) {}

  bool operator <(const Faucet& f) const{
    return (x < f.x);
  }

  bool operator >(const Faucet& f) const{
    return (x > f.x);
  }
  bool operator ==(const Faucet& f) const{
    return (x == f.x);
  }

  bool operator <(const int _x) const{
    return (x < _x);
  }
  bool operator >(const int _x) const{
    return (x > _x);
  }
  bool operator ==(const int _x) const{
    return (x == _x);
  }
};

int main(){
  int total_data_sets;
  while(~scanf("%d",&total_data_sets)){
    for(int data_set_idx = 0; data_set_idx < total_data_sets; data_set_idx++){

      vector<Cell> cells;
      vector<Board> boards;
      int total_boards;
      scanf("%d",&total_boards);

      boards.push_back(Board(0,50));
      for(int board_idx = 0; board_idx < total_boards; board_idx++){
	int x,height;
	scanf("%d %d",&x,&height);
	boards.push_back(Board(x,height));
      }
      boards.push_back(Board(100,50));

      sort(boards.begin(),boards.end());
      for(int src_idx = 0; src_idx < boards.size(); src_idx++){
	if(boards[src_idx].x == 100) continue;

	for(int target_idx = src_idx+1; target_idx < boards.size(); target_idx++){
	  if(boards[target_idx].height < boards[src_idx].height) continue;

	  else if(boards[target_idx].height >= boards[src_idx].height){
	    cells.push_back(Cell(boards[src_idx].height,boards[src_idx].x,boards[target_idx].x));
	    break;
	  }
	}

	for(int target_idx = src_idx-1; target_idx >= 0; target_idx--){
	  if(boards[target_idx].height < boards[src_idx].height) continue;

	  else if(boards[target_idx].height > boards[src_idx].height){
	    cells.push_back(Cell(boards[src_idx].height,boards[target_idx].x,boards[src_idx].x));
	    break;
	  }
	}
      }

      //set brother
      for(int src_idx=0;src_idx<cells.size();src_idx++){
	int height = cells[src_idx].height;

	int target_wall[101];
	memset(target_wall,0,sizeof(target_wall));

	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(target_idx == src_idx) continue;

	  if(cells[src_idx].end_x == cells[target_idx].start_x){
	    target_wall[cells[target_idx].start_x] = max(cells[target_idx].height,target_wall[cells[target_idx].start_x]);
	  }
	  if(cells[src_idx].start_x == cells[target_idx].end_x){
	    target_wall[cells[target_idx].end_x] = max(cells[target_idx].height,target_wall[cells[target_idx].end_x]);
	  }
	}

	int diff = INF;
	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(src_idx == target_idx) continue;
	  if(cells[src_idx].end_x == cells[target_idx].start_x
	     && height == target_wall[cells[target_idx].start_x]
	     && diff > abs(cells[src_idx].end_x - cells[target_idx].end_x)){
	    diff = abs(cells[src_idx].end_x - cells[target_idx].end_x);
	    cells[src_idx].brother = target_idx;
	  }
	  if(cells[src_idx].start_x == cells[target_idx].end_x
	     && height == target_wall[cells[target_idx].end_x]
	     && diff > abs(cells[src_idx].start_x - cells[target_idx].start_x)){
	    diff = abs(cells[src_idx].start_x - cells[target_idx].start_x);
	    cells[src_idx].brother = target_idx;
	  }
	}
      }

      //set parent
      for(int src_idx=0;src_idx<cells.size();src_idx++){
	int min_height = INF;
	int lower_height = cells[src_idx].height;
	for(int target_idx = 0; target_idx < cells.size(); target_idx++){
	  if(src_idx == target_idx) continue;

	  if(cells[src_idx].start_x >= cells[target_idx].start_x
	     && cells[src_idx].end_x <= cells[target_idx].end_x
	     && lower_height <= cells[target_idx].height
	     && min_height > cells[target_idx].height){
	    min_height = cells[target_idx].height;
	    cells[src_idx].parent = target_idx;
	  }
	}

	if(cells[src_idx].parent != -1){
	  cells[cells[src_idx].parent].has_child = true;
	}
      }


      vector<Faucet> faucets;
      int total_faucets;
      scanf("%d",&total_faucets);
      for(int foucet_idx = 0; foucet_idx < total_faucets; foucet_idx++){
	int x,cm3_per_second;
	scanf("%d %d",&x,&cm3_per_second);
	faucets.push_back(Faucet(x,cm3_per_second));
      }

      sort(faucets.begin(),faucets.end());


      int total_observation_times;
      scanf("%d",&total_observation_times);

      vector<Cell> store = cells;
      for(int observation_time_idx = 0; observation_time_idx < total_observation_times; observation_time_idx++){
	int x,time;
	scanf("%d %d",&x,&time);
	
	for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	  for(int faucet_idx = 0; faucet_idx < faucets.size();faucet_idx++){
	    //	  int faucet_idx = lower_bound(faucets.begin(),faucets.end(),cells[cell_idx].start_x) - faucets.begin();
	    if(faucet_idx == faucets.size()) continue;
	    if(faucets[faucet_idx].x < cells[cell_idx].start_x) continue;
	    if(faucets[faucet_idx].x > cells[cell_idx].end_x) continue;
	    if(cells[cell_idx].has_child) continue;
	    
	    cells[cell_idx].pour_water(faucets[faucet_idx].cm3_per_second * time);
	  }
	}


	bool is_erased[1001];
	memset(is_erased,false,sizeof(is_erased));

	for(int round=0;round<10000;round++){
	  for(int src_idx = 0;src_idx < cells.size(); src_idx++){
	    if(is_erased[src_idx]) continue;
	    if(!cells[src_idx].is_filled()) continue;

	    int freq[1001];
	    memset(freq,0,sizeof(freq));

	    int limit = cells.size() * 3;
	    int cell_idx = src_idx;

	    bool isok = true;
	    while(limit-- > 0){
	      if(!cells[cell_idx].is_filled()) break;

	      freq[cell_idx]++;
	      if(freq[cell_idx] >= 3) isok = false;
	      int brother = cells[cell_idx].brother;
	      if(brother == -1) break;
	      cells[brother].water += (cells[cell_idx].water - cells[cell_idx].capacity);
	      cells[cell_idx].water = cells[cell_idx].capacity;
	      cell_idx = brother;
	    }
	    
	    if(isok) continue;

	    int sx = INF;
	    int ex = 0;
	    int water = 0;

	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;

	      if(freq[cell_idx] >= 3){
		sx = min(sx,cells[cell_idx].start_x);
		ex = max(ex,cells[cell_idx].end_x);
		water += cells[cell_idx].water;
		cells[cell_idx].water = 0;
		is_erased[cell_idx] = true;
	      }
	    }
	    
	    int new_cell_idx = 0;
	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;
	      
	      if(sx == cells[cell_idx].start_x 
		 && ex == cells[cell_idx].end_x){

		cells[cell_idx].water = water;
		new_cell_idx = cell_idx;

		break;
	      }
	    }
	    
	    for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	      if(is_erased[cell_idx]) continue;
	      if(cells[cell_idx].brother != -1
		 &&is_erased[cells[cell_idx].brother]){
		cells[cell_idx].brother = new_cell_idx;
	      }
	    }
	  }
	}

	double res= 0.0;
	for(int cell_idx = 0;cell_idx < cells.size(); cell_idx++){
	  if(cells[cell_idx].start_x <= x && x <= cells[cell_idx].end_x){
	    res = max(cells[cell_idx].compute_water_level(),res);
	  }
	}
	printf("%lf\n",res >= 50.0 ? 50.0 : res);
	cells = store;
      }
    }
  }
}
accuracy: 1
time_ms: 180
memory_kb: 1232
final_rank: 5