Problem:
Problem J
  String Puzzle
Amazing Coding Magazine
is popular among young programmers for its puzzle solving contests offering catchy digital gadgets as the prizes. The magazine for programmers naturally encourages the readers to solve the puzzles by writing programs. Let's give it a try!
The puzzle in the latest issue is on deciding some of the letters in a string (
the secret string
, in what follows) based on a variety of hints. The figure below depicts an example of the given hints.
The first hint is the number of letters in the secret string. In the example of the figure above, it is nine, and the nine boxes correspond to nine letters. The letter positions (boxes) are numbered starting from 1, from the left to the right.
The hints of the next kind simply tell the letters in the secret string at some specic positions. In the example, the hints tell that the letters in the 3rd, 4th, 7th, and 9th boxes are
C
,
I
,
C
, and
P
The hints of the final kind are on duplicated substrings in the secret string. The bar immediately
  below the boxes in the figure is partitioned into some sections corresponding to substrings of the secret string. Each of the sections may be connected by a line running to the left with another bar also showing an extent of a substring. Each of the connected pairs indicates that substrings of the two extents are identical. One of this kind of hints in the example tells that the letters in boxes 8 and 9 are identical to those in boxes 4 and 5, respectively. From this, you can easily deduce that the substring is
IP
.
Note that, not necessarily all of the identical substring pairs in the secret string are given in the hints; some identical substring pairs may not be mentioned.
Note also that two extents of a pair may overlap each other. In the example, the two-letter substring in boxes 2 and 3 is told to be identical to one in boxes 1 and 2, and these two extents share the box 2.
In this example, you can decide letters at all the positions of the secret string, which are "
CCCIPCCIP
". In general, the hints may not be enough to decide all the letters in the secret string.
The answer of the puzzle should be letters at the specified positions of the secret string. When the letter at the position specified cannot be decided with the given hints, the symbol
?
should be answered.
Input
The input consists of a single test case in the following format.
$n$ $a$ $b$ $q$
$x_1$ $c_1$
...
$x_a$ $c_a$
$y_1$ $h_1$
...
$y_b$ $h_b$
$z_1$
...
$z_q$
The first line contains four integers $n$, $a$, $b$, and $q$. $n$ ($1 \leq n \leq 10^9$) is the length of the secret string, $a$ ($0 \leq a \leq 1000$) is the number of the hints on letters in specified positions, $b$ ($0 \leq b \leq 1000$) is the number of the hints on duplicated substrings, and $q$ ($1 \leq q \leq 1000$) is the number of positions asked.
The $i$-th line of the following a lines contains an integer $x_i$ and an uppercase letter $c_i$ meaning that the letter at the position $x_i$ of 
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1LL << 60;
#define rep(i, a) for(ll i = 0; i < (a); i++)
#define all(a) begin(a), end(a)
#define sz(a) (a).size()
bool chmax(auto &a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmin(auto &a, auto b) { return a < b ? a = b, 1 : 0; }
void out() { cout << endl; }
template<class T, class... Ts> void out(const T& a, const Ts&... b){ cout<<a; (cout<<... << (cout << ' ', b)); cout << endl;}
using vll = vector<ll>;
using vvll = vector<vll>;

int main()
{
  ll N, A, B, Q; cin >> N >> A >> B >> Q;
  vll X(A), Y(B + 1, 1), H(B + 1, 0), Z(Q);
  vector<char> C(A);
  rep(i, A) cin >> X[i] >> C[i];
  rep(i, B) cin >> Y[i + 1] >> H[i + 1];
  rep(i, Q) cin >> Z[i];
  map<ll, char> query;
  function<void(ll, char)> addc = [&](ll x, char c)
  {
    ll ib = distance(Y.begin(), upper_bound(all(Y), x)) - 1;
    if(H[ib] == 0)
    {
      query[x] = c;
      return;
    }
    ll pos = x - Y[ib];
    ll l = Y[ib] - H[ib];
    ll nx = H[ib] + pos % l;
    addc(nx, c);
  };
  rep(i, A) addc(X[i], C[i]);
  function<char(ll)> findc = [&](ll x)
  {
    ll ib = distance(Y.begin(), upper_bound(all(Y), x)) - 1;
    if(H[ib] == 0)
    {
      if(query.count(x)) return query[x];
      else return '?';
    }
    ll pos = x - Y[ib];
    ll l = Y[ib] - H[ib];
    ll nx = H[ib] + pos % l;
    return findc(nx);
  };
  rep(i, Q) cout << findc(Z[i]);
  out("");
}
accuracy: 1
time_ms: 60
memory_kb: 3712
final_rank: 13

code_snippet: #include<cstdio>
#include<map>
using namespace std;
const int N=1100;
int n,a,b,q,i,x,m,known[N];char ch[N][9];
int y[N],h[N];
map<int,char>T;
struct E{int l,d;E(){}E(int _l,int _d){l=_l,d=_d;}}e[N];
inline int go(int x){
	int i=m;
	while(1){
		while(i&&e[i].l>x)i--;
		int l=e[i].l,d=e[i].d;
		if(!i||!d)break;
		x-=(x-l)/d*d;
		while(x>=l)x-=d;
	}
	return x;
}
int main(){
	scanf("%d%d%d%d",&n,&a,&b,&q);
	for(i=1;i<=a;i++)scanf("%d%s",&known[i],ch[i]);
	for(i=1;i<=b;i++)scanf("%d%d",&y[i],&h[i]);
	y[b+1]=n+1;
	for(i=1;i<=b;i++)e[++m]=E(y[i],h[i]?y[i]-h[i]:0);
	for(i=1;i<=a;i++)T[go(known[i])]=ch[i][0];
	while(q--){
		scanf("%d",&x);
		x=go(x);
		if(T.find(x)==T.end())putchar('?');else putchar(T[x]);
	}
puts("");
}
accuracy: 1
time_ms: 10
memory_kb: 3064
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vl = vector<ll>;
#define rep(i, n) for(ll i = 0; i < (ll)n; ++i)
#define loop(i, a, b) for(ll i = a; i <= b; ++i)
constexpr ll INF = 9009009009009009009LL;

vl y,h,mds;

ll dfs(ll x){
	ll i = upper_bound(y.begin(),y.end(),x)-y.begin()-1;
	ll tmp = x-y[i];
	tmp %= mds[i];
	if(h[i]==-1)return x;
	return dfs(h[i]+tmp);
}

int main(){
    ll n,a,b,q;
	cin>>n>>a>>b>>q;
	vl x(a);
	string c(a,'.');
	rep(i,a)cin>>x[i]>>c[i],x[i]--;

	y=vl(b+2,0);
	h=vl(b+1,-1);
	y[b+1]=n;

	loop(i,1,b)cin>>y[i]>>h[i],y[i]--,h[i]--;

	mds=vl(b+1);
	rep(i,b+1){
		mds[i]=y[i+1]-y[i];
		if(h[i]!=-1){
			mds[i]=min(mds[i],y[i]-h[i]);
		}
		//cout<<mds[i]<<endl;
	}

	map<ll,char> ans;

	rep(i,a){
		ans[dfs(x[i])]=c[i];
	}


	while(q--){
		ll z;
		cin>>z;
		z--;
		ll tmp=dfs(z);
		if(ans.count(tmp))cout<<ans[tmp];
		else cout<<"?";
	}
	cout<<endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define rep(i,s,n) for (int i = (int)(s); i < (int)(n); i++)
#define all(v) begin(v),end(v)
using namespace std;
using ll = long long;
bool chmin(auto &a, auto b){ return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b){ return a < b ? a = b, 1 : 0; }

using pii = pair<int,int>;


void solve() {
    int n, a, b, q; cin >> n >> a >> b >> q;
    vector<pair<int,char>> hint(a);
    rep(i,0,a) {
        int x; cin >> x; x--;
        char c; cin >> c;
        hint[i] = {x, c};
    }
    vector<int> ys(b+1);
    vector<int> hs(b+1,-1);
    ys[b] = n;
    rep(i,0,b) {
        int y, h; cin >> y >> h; y--, h--;
        ys[i] = y;
        hs[i] = h;
    }
    int cnt = 0;
    // rep(i,0,b) cout << hs[i] << endl;
    auto dfs = [&](auto sfs, int x) -> int {
        int id = upper_bound(all(ys),x) - ys.begin() - 1;
        if (id < 0) return x;
        if (hs[id] == -1) return x;
        int k = (x - ys[id]) / (ys[id] - hs[id]) + 1;
        return sfs(sfs,x + k * (hs[id] - ys[id]));
    };
    auto go = [&](int x) {
        return dfs(dfs,x);
    };
    // cout << "ok" << endl;
    for (auto &[x, c] : hint) {
        x = go(x);
    }
    rep(i,0,q) {
        int z; cin >> z; z--;
        z = go(z);
        // cout << "go z" << endl;
        char ans = '?';
        for (auto [x, c] : hint) {
            if (x == z) {
                ans = c;
            }
        }
        cout << ans;
    }
    cout << endl;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    solve();
}
accuracy: 1
time_ms: 30
memory_kb: 3584
final_rank: 7

code_snippet: #include <bits/extc++.h>

using ll = long long;
using pll = std::pair<ll, ll>;
using pli = std::pair<ll, int>;
using pii = std::pair<int, int>;

template <class T>
bool chmax(T& x, const T& v) {
  if (x < v) {
    x = v;
    return true;
  } else {
    return false;
  }
}

int main() {
  ll N, A, B, Q;
  std::cin >> N >> A >> B >> Q;
  std::vector<std::pair<ll, char>> hint1(A);
  std::vector<pll> hint2(B);
  std::vector<ll> queries(Q);
  std::vector<ll> ys;
  for (auto& [x, c] : hint1) {
    std::cin >> x >> c;
    x--;
  }
  for (auto& [y, h] : hint2) {
    std::cin >> y >> h;
    y--;
    h--;
    ys.push_back(y);
  }
  for (auto& z : queries) {
    std::cin >> z;
    z--;
  }

  std::vector<ll> roomsize(B + 1);

  if (B) {
    roomsize.front() = ys[0];
    roomsize.back() = N - ys.back();
    for (int i = 0; i < B - 1; i++) {
      roomsize[i + 1] = ys[i + 1] - ys[i];
    }
  } else {
    roomsize[0] = N;
  }

  auto roommod = [&](int id) -> ll {
    if (id == 0 || hint2[id - 1].second < 0) {
      return N;
    } else {
      return hint2[id - 1].first - hint2[id - 1].second;
    }
  };

  auto roomhead = [&](int id) -> ll {
    if (id == 0) {
      return 0;
    } else {
      return hint2[id - 1].first;
    }
  };

  std::vector<std::pair<std::vector<pli>, std::vector<pli>>> rooms(B + 1);

  for (int i = 0; i < A; i++) {
    int roomno =
        std::upper_bound(ys.begin(), ys.end(), hint1[i].first) - ys.begin();
    rooms[roomno].first.emplace_back(
        (hint1[i].first - roomhead(roomno)) % roommod(roomno), i);
  }
  for (int i = 0; i < Q; i++) {
    int roomno =
        std::upper_bound(ys.begin(), ys.end(), queries[i]) - ys.begin();
    rooms[roomno].second.emplace_back(
        (queries[i] - roomhead(roomno)) % roommod(roomno), i);
  }
  //   for (auto& [hs, qs] : rooms) {
  //     std::sort(hs.begin(), hs.end());
  //     std::sort(qs.begin(), qs.end());
  //   }

  std::string ans(Q, '?');

  for (int i = B; i >= 0; i--) {
    auto& [hs, qs] = rooms[i];
    std::sort(hs.begin(), hs.end());
    std::sort(qs.begin(), qs.end());

    if (false) {
      std::cerr << "room " << i << ":\nhints:\n";
      for (auto [x, i] : hs) {
        std::cerr << x << " " << i << std::endl;
      }
      std::cerr << "queries:\n";
      for (auto [x, i] : qs) {
        std::cerr << x << " " << i << std::endl;
      }
    }

    for (int x = 0, y = 0; x < hs.size() && y < qs.size(); x++) {
      while (y < qs.size() && qs[y].first < hs[x].first) {
        y++;
      }
      while (y < qs.size() && qs[y].first == hs[x].first) {
        ans[qs[y].second] = hint1[hs[x].second].second;
        y++;
      }
    }

    if (i > 0 && hint2[i - 1].second >= 0) {
      for (int p = 0; p < qs.size(); p++) {
        if (ans[qs[p].second] != '?') continue;
        int roomno = std::upper_bound(ys.begin(), ys.end(),
                                      hint2[i - 1].second + qs[p].first) -
                     ys.begin();
        assert(roomno != i);
        rooms[roomno].second.emplace_back(
            (hint2[i - 1].second + qs[p].first - roomhead(roomno)) %
                roommod(roomno),
            qs[p].second);
      }

      for (int p = 0; p < hs.size(); p++) {
        int roomno = std::upper_bound(ys.begin(), ys.end(),
                                      hint2[i - 1].second + hs[p].first) -
                     ys.begin();
        assert(roomno != i);
        rooms[roomno].first.emplace_back(
            (hint2[i - 1].second + hs[p].first - roomhead(roomno)) %
                roommod(roomno),
            hs[p].second);
      }
    }
  }

  std::cout << ans << std::endl;
}
accuracy: 1
time_ms: 40
memory_kb: 35584
final_rank: 16

code_snippet: #include <bits/extc++.h>

using ll = long long;
using pll = std::pair<ll, ll>;
using pli = std::pair<ll, int>;
using pii = std::pair<int, int>;

template <class T>
bool chmax(T& x, const T& v) {
  if (x < v) {
    x = v;
    return true;
  } else {
    return false;
  }
}

int main() {
  ll N, A, B, Q;
  std::cin >> N >> A >> B >> Q;
  std::vector<std::pair<ll, char>> hint1(A);
  std::vector<pll> hint2(B);
  std::vector<ll> queries(Q);
  std::vector<ll> ys;
  for (auto& [x, c] : hint1) {
    std::cin >> x >> c;
    x--;
  }
  for (auto& [y, h] : hint2) {
    std::cin >> y >> h;
    y--;
    h--;
    ys.push_back(y);
  }
  for (auto& z : queries) {
    std::cin >> z;
    z--;
  }

  std::vector<ll> roomsize(B + 1);

  if (B) {
    roomsize.front() = ys[0];
    roomsize.back() = N - ys.back();
    for (int i = 0; i < B - 1; i++) {
      roomsize[i + 1] = ys[i + 1] - ys[i];
    }
  } else {
    roomsize[0] = N;
  }

  auto roommod = [&](int id) -> ll {
    if (id == 0) {
      return N;
    } else {
      return hint2[id - 1].first - hint2[id - 1].second;
    }
  };

  auto roomhead = [&](int id) -> ll {
    if (id == 0) {
      return 0;
    } else {
      return hint2[id - 1].first;
    }
  };

  std::vector<std::pair<std::vector<pli>, std::vector<pli>>> rooms(B + 1);

  for (int i = 0; i < A; i++) {
    int roomno =
        std::upper_bound(ys.begin(), ys.end(), hint1[i].first) - ys.begin();
    rooms[roomno].first.emplace_back(
        (hint1[i].first - roomhead(roomno)) % roommod(roomno), i);
  }
  for (int i = 0; i < Q; i++) {
    int roomno =
        std::upper_bound(ys.begin(), ys.end(), queries[i]) - ys.begin();
    rooms[roomno].second.emplace_back(
        (queries[i] - roomhead(roomno)) % roommod(roomno), i);
  }
  //   for (auto& [hs, qs] : rooms) {
  //     std::sort(hs.begin(), hs.end());
  //     std::sort(qs.begin(), qs.end());
  //   }

  std::string ans(Q, '?');

  for (int i = B; i >= 0; i--) {
    auto& [hs, qs] = rooms[i];
    std::sort(hs.begin(), hs.end());
    std::sort(qs.begin(), qs.end());

    if (false) {
      std::cerr << "room " << i << ":\nhints:\n";
      for (auto [x, i] : hs) {
        std::cerr << x << " " << i << std::endl;
      }
      std::cerr << "queries:\n";
      for (auto [x, i] : qs) {
        std::cerr << x << " " << i << std::endl;
      }
    }

    for (int x = 0, y = 0; x < hs.size() && y < qs.size(); x++) {
      while (y < qs.size() && qs[y].first < hs[x].first) {
        y++;
      }
      while (y < qs.size() && qs[y].first == hs[x].first) {
        ans[qs[y].second] = hint1[hs[x].second].second;
        y++;
      }
    }

    if (i > 0 && hint2[i - 1].second >= 0) {
      for (int p = 0; p < qs.size(); p++) {
        if (ans[qs[p].second] != '?') continue;
        int roomno = std::upper_bound(ys.begin(), ys.end(),
                                      hint2[i - 1].second + qs[p].first) -
                     ys.begin();
        rooms[roomno].second.emplace_back(
            (hint2[i - 1].second + qs[p].first - roomhead(roomno)) %
                roommod(roomno),
            qs[p].second);
      }

      for (int p = 0; p < hs.size(); p++) {
        int roomno = std::upper_bound(ys.begin(), ys.end(),
                                      hint2[i - 1].second + hs[p].first) -
                     ys.begin();
        rooms[roomno].first.emplace_back(
            (hint2[i - 1].second + hs[p].first - roomhead(roomno)) %
                roommod(roomno),
            hs[p].second);
      }
    }
  }

  std::cout << ans << std::endl;
}
accuracy: 0.6190476190476191
time_ms: 40
memory_kb: 35584
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,a,b) for(ll i = a; i < b; i++)
#define all(a) (a).begin(), (a).end()

int main(){
    ll n,a,b,q;
    cin >> n >> a >> b >> q;
    vector<ll>x(a),y(b+2,0),h(b+2,0);
    vector<char> c(a);
    rep(i,0,a){
        cin >> x[i] >> c[i];
    }
    rep(i,0,b){
        cin >> y[i+1] >> h[i+1];
    }
    y[b+1] = n+1;

    
    auto calc = [&](auto calc, ll nw) -> ll {
        int i = upper_bound(all(y), nw) - y.begin() -1;
        if(h[i] == 0) return nw;
        ll len = y[i+1] - y[i];
        ll st = h[i];
        if(y[i] <= st + len){
            ll g = y[i] - st;
            ll res = (nw - y[i]) / g + 1;
            return calc(calc, nw - res * g); 
        }else{
            return calc(calc, st + nw - y[i]);
        }
    };

    map<ll,ll> mp;
    rep(i,0,a){
        mp[calc(calc, x[i])] = c[i] - 'A' + 1;
    }
    rep(i,0,q){
        int z;
        cin >> z;
        ll res = mp[calc(calc, z)];
        if(res == 0){
            cout << '?';
        }else{
            cout << ((char)('A' + res - 1));
        }
    }
    cout << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 8

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, A, B, Q;
    cin >> N >> A >> B >> Q;
    vector<int> X(A);
    vector<char> C(A);
    vector<int> Y(B), H(B);
    rep(i,0,A) cin >> X[i] >> C[i];
    rep(i,0,B) cin >> Y[i] >> H[i];
    Y.push_back(N+1);
    map<int,char> mp;
    rep(i,0,A) {
        while(X[i] >= Y[0]) {
            int id = UB(Y,X[i])-1;
            if (H[id] == 0) break;
            X[i] -= (Y[id]-H[id]) * ceil(X[i]-Y[id]+1,Y[id]-H[id]);
        }
        mp[X[i]] = C[i];
    }
    rep(i,0,Q) {
        int Z;
        cin >> Z;
        while(Z >= Y[0]) {
            int id = UB(Y,Z)-1;
            if (H[id] == 0) break;
            Z -= (Y[id]-H[id]) * ceil(Z-Y[id]+1,Y[id]-H[id]);
        }
        if (mp.count(Z)) cout << mp[Z];
        else cout << '?';
    }
    cout << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 3448
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using vll=vector<ll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)

ll pos(ll x, vll& Y, vll& H) {
    ll d = upper_bound(Y.begin(), Y.end(), x) - Y.begin();
    if (d == 0||H[d-1]==-1)return x;
    d--;
    return pos((x - Y[d]) % (Y[d] - H[d]) + H[d], Y, H);
}

int main() {
    ll N, A, B, Q, p;
    cin >> N >> A >> B >> Q;
    vector<ll> X(A),Y(B), H(B);;
    vector<char> C(A);
    rep(a, A)cin >> X[a] >> C[a], X[a]--;
    rep(b, B)cin >> Y[b] >> H[b], Y[b]--, H[b]--;
    map<ll, char> M;
    rep(a, A)M[pos(X[a], Y, H)] = C[a];
    rep(q, Q) {
        cin >> p;
        p = pos(p - 1, Y, H);
        cout << (M.count(p) ? M[p] : '?');
    }
    cout << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 3528
final_rank: 15

code_snippet: // #pragma GCC target("avx2")
#pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<sys/time.h>
// #include<atcoder/dsu>

using namespace std;

// using mint = atcoder::modint998244353;

const int M = 1000000007;
const long long LM = 1LL << 60;

using P = pair<int, int>;



int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    int n, a, b, q;
    cin >> n >> a >> b >> q;
    vector<int> x(a);
    vector<char> c(a);
    for (int i = 0; i < a; ++i) {
        cin >> x[i] >> c[i];
        --x[i];
    }
    vector<int> y(b), d(b);
    for (int i = 0; i < b; ++i) {
        cin >> y[i] >> d[i];
        if (d[i]) {
            d[i] = y[i] - d[i];
        }
        --y[i];
    }
    auto get = [&](int x) {
        for (int i = (int)y.size() - 1; i >= 0; --i) {
            if (x < y[i]) {
                continue;
            }
            if (d[i] == 0) {
                break;
            }
            x -= ((x - y[i]) / d[i] + 1) * d[i];
        }
        return x;
    };
    unordered_map<int, char> mp;
    for (int i = 0; i < a; ++i) {
        mp[get(x[i])] = c[i];
    }
    for (int _ = 0; _ < q; ++_) {
        int z;
        cin >> z;
        --z;
        z = get(z);
        if (mp.count(z)) {
            cout << mp[z];
        }
        else {
            cout << '?';
        }
    }
    cout << '\n';


    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3512
final_rank: 3

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

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define each(e, x) for (auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template <typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }
TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }
TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main() {
    int n, a, b, q;
    cin >> n >> a >> b >> q;
    vector<int> x(a);
    vector<char> c(a);
    rep(i, a) cin >> x[i] >> c[i];
    vector<int> y(b + 2), h(b + 2, 0);
    y[0] = 1, y[b + 1] = n + 1;
    rep2(i, 1, b + 1) cin >> y[i] >> h[i];
    auto calc = [&](int p) {
        while (1) {
            int idx = ub(y, p) - 1;
            if (h[idx] == 0)
                break;
            p = (p - y[idx]) % (y[idx] - h[idx]) + h[idx];
        }
        return p;
    };
    vector<int> ps(a);
    rep(i, a) ps[i] = calc(x[i]);
    while (q--) {
        int z;
        cin >> z;
        z = calc(z);
        char ans = '?';
        rep(i, a) if (ps[i] == z) ans = c[i];
        cout << ans;
    }
    cout << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 3476
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i = a; i < (b); i++)
#define all(x) begin(x),end(x)
#define sz(x) (int)(x).size()
#define PB push_back
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;

unordered_map<int, int> ojc;
unordered_map<int, int> litojc;

char lit[5002];
int pos[5002], query[5002];
int y[5002], h[5002];

void aktu(int n) {
    if (ojc[n] == 0) {
        ojc[n] = n;
        return;
    }
    if (ojc[n] != ojc[ojc[n]]) {
        aktu(ojc[n]);
        ojc[n] = ojc[ojc[n]];
    }
}

void unionuj(int a, int b) {
    aktu(a);
    aktu(b);
    a = ojc[a];
    b = ojc[b];
    if (litojc[b]) {
        swap(a, b);
    }
    ojc[b] = a;
}

void rekunion(int akt, int b) {
    int num = b - 1;
    while (akt >= y[0]) {
        while (y[num] > akt) {
            num--;
        }
        if (h[num] == 0)
            break;
        int diff = y[num] - h[num];
        int nakt = (akt - y[num]) % diff + y[num];
        unionuj(akt, nakt);
        nakt = (akt - y[num]) % diff + h[num];
        unionuj(akt, nakt);
        akt = nakt;
    }
}

signed main(){
	cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit);
    int n, a, b, q;
    cin >> n >> a >> b >> q;
    for (int i = 0; i < a; i++) {
        cin >> pos[i] >> lit[i];
    }
    for (int i = 0; i < b; i++) {
        cin >> y[i] >> h[i];
    }
    for (int i = 0; i < q; i++) {
        cin >> query[i];
        aktu(query[i]);
        rekunion(query[i], b);
    }
    for (int i = 0; i < a; i++) {
        aktu(pos[i]);
        litojc[ojc[pos[i]]] = lit[i];
        rekunion(pos[i], b);
    }
    for (int i = 0; i < q; i++) {
        aktu(query[i]);
        if (litojc[ojc[query[i]]]) {
            cout << (char)litojc[ojc[query[i]]];
        } else {
            cout << "?";
        }
    }
    cout << "\n";
}
accuracy: 1
time_ms: 800
memory_kb: 190060
final_rank: 19

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

int N, A, B, Q;
vector<int> X, Y, H;
vector<char> C;

unordered_map<int, int> book;

int maine(int p) {
    if (book.count(p))
        return book[p];
    int& ret = book[p];
    for (int i = B - 1; i >= 0; i--) {
        int h = H[i];
        if (h == -1)
            continue;
        int y = Y[i];
        int l = (i == B - 1 ? N : Y[i + 1]) - y;
        int d = y - h;
        if (y <= p && p < y + l) {
            p = h + ((p - y) % d);
        }
    }
    return ret = p;
}

int main() {
    cin >> N >> A >> B >> Q;
    X.resize(A);
    C.resize(A);
    for (int i = 0; i < A; i++) {
        cin >> X[i] >> C[i];
        X[i]--;
    }
    Y.resize(B);
    H.resize(B);
    for (int i = 0; i < B; i++) {
        cin >> Y[i] >> H[i];
        Y[i]--;
        H[i]--;
    }

    unordered_map<int, char> honzuki;
    for (int i = 0; i < A; i++) {
        X[i] = maine(X[i]);
        honzuki[X[i]] = C[i];
    }

    while (Q--) {
        int z;
        cin >> z;
        z--;
        z = maine(z);
        char ans;
        if (honzuki.count(z))
            ans = honzuki[z];
        else
            ans = '?';
        cout << ans;
    }
    cout << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int n, a, b, q;
    cin >> n >> a >> b >> q;
    vector<int> x(a);
    vector<char> c(a);
    rep(i,0,a) cin >> x[i] >> c[i];
    vector<int> y(b+1), h(b+1);
    y[b] = n + 1;
    rep(i,0,b) cin >> y[i] >> h[i];

    auto move_left = [&](int x) {
        int i = b-1;
        while (i >= 0) {
            if (y[i] <= x && x < y[i+1] && h[i] > 0) {
                int len = y[i+1] - y[i] + h[i] - y[i];
                int g = gcd(y[i+1] - y[i], len);
                int a = (y[i] - h[i]) / g;
                int k = (x - y[i]) / (a * g);
                x -= a * g * k + y[i] - h[i];
            }
            --i;
        }
        return x;
    };

    map<int, char> hints;
    rep(i,0,a) {
        hints[move_left(x[i])] = c[i];
    }

    string s = "";
    rep(_,0,q) {
        int z;
        cin >> z;
        z = move_left(z);
        if (hints.count(z)) s += hints[z];
        else s += '?';
    }
    cout << s << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3512
final_rank: 3

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

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

void solve() {
  int n, a, b, q;
  cin >> n >> a >> b >> q;
  vector<int> x(a), y(b + 2), h(b + 2, -1), z(q);
  vector<char> c(a);
  for (int i = 0; i < a; i++) {
    cin >> x[i] >> c[i];
    x[i]--;
  }
  for (int i = 1; i <= b; i++) {
    cin >> y[i] >> h[i];
    y[i]--;
    h[i]--;
  }
  y[0] = 0, y[b + 1] = n;
  for (int i = 0; i < q; i++) {
    cin >> z[i];
    z[i]--;
  }
  function<int(int)> normalize = [&](int pos) {
    int k = upper_bound(all(y), pos) - y.begin();
    if (k == 1) return pos;
    k--;
    if (h[k] == -1) return pos;
    int w = y[k] - h[k];
    assert(w > 0);
    if (pos - w >= y[k]) {
      int qos = (y[k] / w + 1) * w + pos % w;
      while (qos >= y[k]) qos -= w;
      return normalize(qos);
    }
    return normalize(pos - w);
  };

  map<int, char> m;
  for (int i = 0; i < a; i++) { m[normalize(x[i])] = c[i]; }

  string ans;
  for (int i = 0; i < q; i++) {
    auto it = m.find(normalize(z[i]));
    if (it == m.end())
      ans += '?';
    else
      ans += it->second;
  }

  cout << ans << endl;

  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3520
final_rank: 14

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

using namespace std;

void solve() {
    int l, n, m, q;
    cin >> l >> n >> m >> q;

    vector<pair<int, char>> ps(n);
    for (auto& [x, c] : ps) {
        cin >> x >> c;
    }

    vector<int> ys(m), zs(m);
    for (int i = 0; i < m; ++i) cin >> ys[i] >> zs[i];
    ys.push_back(l + 1);

    // x文字目と等しい最小のindex
    auto lpos = [&](int x) {
        for (int i = m - 1; i >= 0; --i) {
            auto lx = ys[i], rx = ys[i + 1], llx = zs[i];

            if (lx <= x && x < rx && llx != 0) {
                x = llx + (x - llx) % (lx - llx);
            }
        }
        return x;
    };

    map<int, char> info;
    for (auto [x, c] : ps) info[lpos(x)] = c;

    while (q--) {
        int x;
        cin >> x;
        x = lpos(x);
        cout << (info.count(x) ? info[x] : '?');
    }
    cout << "\n";
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3532
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=305,INF=1<<29;

int main() {
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N,A,B,Q;cin>>N>>A>>B>>Q;
    vector<int> x(A),y(B),h(B);
    vector<char> c(A);
    
    for(int i=0;i<A;i++){
        cin>>x[i]>>c[i];
    }
    for(int i=0;i<B;i++){
        cin>>y[i]>>h[i];
    }
    y.push_back(N+1);
    map<int,char> MA;
    for(int i=0;i<A;i++){
        int now=x[i];
        while(1){
            bool f=false;
            for(int j=0;j<B;j++){
                if(h[j]==0) continue;
                if(y[j]<=now&&now<y[j+1]){
                    f=true;
                    now=(now-y[j])%(y[j]-h[j])+h[j];
                    break;
                }
            }
            if(!f) break;
        }
        MA[now]=c[i];
    }
    
    while(Q--){
        int now;cin>>now;
        while(1){
            bool f=false;
            for(int j=0;j<B;j++){
                if(h[j]==0) continue;
                if(y[j]<=now&&now<y[j+1]){
                    f=true;
                    now=(now-y[j])%(y[j]-h[j])+h[j];
                    break;
                }
            }
            if(!f) break;
        }
        if(MA.count(now)) cout<<MA[now];
        else cout<<'?';
    }
    cout<<endl;
}
accuracy: 1
time_ms: 680
memory_kb: 3524
final_rank: 18

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{

    void solve(){
        int n,m;
        int p,q,r;
        int i,j,k;
        int a,b,c;
        char ca;
        map<int,char> m1;
        cin>>n>>p>>q>>r;
        vector<pair<int,char>> v1;
        for(i=0;i<p;i++){
            cin>>a>>ca;
            a--;
            v1.push_back({a,ca});
        }
        vector<P> vp;
        for(i=0;i<q;i++){
            cin>>a>>b;
            if(b)b=a-b;
            a--;
            vp.push_back({a,b});
        }
        for(i=0;i<p;i++){
            a=v1[i].first;
            for(j=q-1;j>=0;j--){
                if(a<vp[j].first)continue;
                if(vp[j].second==0)break;
                a-=((a-vp[j].first)/vp[j].second+1)*vp[j].second;
            }
            v1[i].first=a;
        }
        sort(v1.begin(),v1.end());
        for(i=0;i<r;i++){
            cin>>a;
            a--;
            char cs='?';
            for(j=q-1,k=p-1;j>=0 && k>=0;j--){
                if(a<vp[j].first)continue;
                for(;k>=0;k--){
                    if(a<v1[k].first)continue;
                    if(v1[k].first<vp[j].first)break;
                    if(a==v1[k].first || (vp[j].second && (a-v1[k].first)%vp[j].second==0)){
                        cs=v1[k].second;
                        break;
                    }
                }
                if(cs!='?')break;
                if(vp[j].second==0)break;
                a-=((a-vp[j].first)/vp[j].second+1)*vp[j].second;
            }
            for(;k>=0;k--){
                if(a==v1[k].first)cs=v1[k].second;
            }
            cout<<cs;
        }
        cout<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3488
final_rank: 2

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#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<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

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

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr 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++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 22;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

void solve() {
	int n, a, b, q; cin >> n >> a >> b >> q;
	vector<int> x(a);
	vector<char> c(a);
	rep(i, a)cin >> x[i] >> c[i];
	vector<int> y(b + 1), h(b);
	rep(i, b) {
		cin >> y[i] >> h[i];
	}
	y[b] = n + 1;
	vector<int> z(q);
	rep(i, q)cin >> z[i];
	auto genelize = [&](int loc)->int {
		per(j, b) {
			if (y[j] <= loc && loc < y[j + 1] && h[j]>0) {
				int dif = loc - y[j];
				int d = dif / (y[j] - h[j]);
				loc -= (d + 1) * (y[j] - h[j]);
			}
		}
		return loc;
	};
	map<int, char> mp;
	rep(i, a) {
		int loc = genelize(x[i]);
		mp[loc] = c[i];
	}
	string ans;
	rep(i, q) {
		int loc = genelize(z[i]);
		if (mp.find(loc) == mp.end()) {
			ans.push_back('?');
		}
		else {
			ans.push_back(mp[loc]);
		}
	}
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 69080
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
using namespace std;

int main(){
    int n,a,b,q;
    cin >> n >> a >> b >> q;
    vector<pair<int,char>> pos(a);
    for(int i=0; i<a; i++){
        int p;
        char c;
        cin >> p >> c;
        p--;
        pos[i] = {p, c};
    }
    vector<pair<int,int>> same(b+1, {0, -1});
    for(int i=0; i<b; i++){
        int x,y;
        cin >> x >> y;
        x--; y--;
        same[i+1] = {x, y};
    }
    vector<int> query(q);
    for(int i=0; i<q; i++){
        cin >> query[i];
        query[i]--;
    }
    map<int, char> dict;
    for(auto p: pos){
        int x = p.first;
        while(1){
            auto itr = upper_bound(same.begin(), same.end(), make_pair(x, x))-1;
            int y = itr->first;
            int h = itr->second;
            if(h == -1) break;
            x = h + (x-y)%(y-h);
        }
        dict[x] = p.second;
    }
    string ans = "";
    for(int i: query){
        int x = i;
        while(1){
            auto itr = upper_bound(same.begin(), same.end(), make_pair(x, x))-1;
            int y = itr->first;
            int h = itr->second;
            if(h == -1) break;
            x = h + (x-y)%(y-h);
        }
        if(dict.count(x) == 0){
            ans += "?";
        }else{
            ans += dict[x];
        }
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3508
final_rank: 11