/* Sqrt solution */ #include #include #include #include #define mp make_pair #define PII pair #define fi first #define se second using namespace std; const int NMAX = 100005; int n,Q; int station[NMAX]; //blocks int len, ind[NMAX], prev_block[NMAX], next_block[NMAX], sum[NMAX]; int size[NMAX]; //size[i] = size of i-th block int st[NMAX], dr[NMAX]; //queries int ans[NMAX], a[NMAX], b[NMAX], c[NMAX]; int act_size[NMAX]; vectorv[NMAX]; vectort; void Preprocess() { int i; for (i = 1; i <= n; i++) { if ((station[i] == 0 && station[i - 1] == 1) || (station[i] == 0 && i == 1)) //start new block at i { len++; st[len] = i; } if (station[i] == 0) { ind[i] = len; size[len]++; dr[len] = i; } } //make prev and next_block int last = 0; for (i = 1; i <= n; i++) { last = max(last, ind[i]); if (station[i] == 1) { prev_block[i] = last; next_block[i] = last + 1; //always } } } PII Find(int x, int y) { int block_x = ind[x] + 1, block_y = ind[y] - 1; if (station[x] == 1) //go next block_x = next_block[x]; if (station[y] == 1) //go prev block_y = prev_block[y]; if (block_x <= block_y) //surely this is good return mp(block_x, block_y); return mp(0, 0); } int main() { //freopen("input", "r", stdin); //freopen("output", "w", stdout); cin.sync_with_stdio(false); //read string s; cin >> n >> s; for (int i = 1; i <= n; i++) station[i] = (int)(s[i - 1] - '0'); Preprocess(); int sq = sqrt(n); //queries cin >> Q; for (int j = 1; j <= Q; j++) { cin >> a[j] >> b[j] >> c[j]; v[c[j]].push_back(j); } //small-queries for (int i = 1; i <= sq; i++) if (v[i].size() > 0) { //remake act_size for (int j = 1; j <= len; j++) { act_size[j] = size[j] / i; sum[j] = sum[j - 1] + act_size[j]; } //answer for (auto it : v[i]) { if (a[it] == b[it]) continue; b[it]--; int A = a[it], B = b[it]; PII range = Find(A, B); //find the range of full blocks contained in path A -> B //add what's left from A if (station[A] == 0) { int mn = min(B, dr[ind[A]]); ans[it] += (mn - A) / c[it]; A = mn + 1; } //add what's left from B if (station[B] == 0 && B >= A) ans[it] += (B - st[ind[B]] + 1) / c[it]; if (range.fi > 0) ans[it] += sum[range.se] - sum[range.fi - 1]; } } for (int i = 1; i <= len; i++) if (size[i] > sq) t.push_back(i); //big-queries for (int i = sq + 1; i <= n; i++) for (auto it : v[i]) { if (a[it] == b[it]) continue; b[it]--; int A = a[it], B = b[it]; PII range = Find(A, B); //find the range of full blocks contained in path A -> B //add what's left from A if (station[A] == 0) { int mn = min(B, dr[ind[A]]); ans[it] += (mn - A) / c[it]; A = mn + 1; } //add what's left from B if (station[B] == 0 && B >= A) ans[it] += (B - st[ind[B]] + 1) / c[it]; //search through all segments bigger than sqrt for (auto pit : t) if (st[pit] >= A && dr[pit] <= B) ans[it] += size[pit] / c[it]; } //output for (int i = 1; i <= Q; i++) cout << ans[i] << "\n"; return 0; }