Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // #include <bits/stdc++.h>
- #include <iostream>
- #include <algorithm>
- #include <map>
- #include <set>
- #include <vector>
- #include <string>
- #include <climits>
- #include <queue>
- #include <sstream>
- #include <numeric>
- #include <stdlib.h>
- #include <stack>
- #include <cmath>
- #include <bitset>
- #include <unordered_map>
- #include <unordered_set>
- #include <iomanip>
- #include <cstring>
- #include <utility>
- #include <cassert>
- #include <fstream>
- #include <regex>
- using namespace std;
- //#define int long long
- // 1-Index Segment Tree
- class SegmentTree1{
- private:
- vector<vector<vector<int>>> m_tree;
- int n;
- void combine(int i, int j, int index){
- // merge(m_tree[i].begin(), m_tree[i].end(), m_tree[j].begin(), m_tree[j].end(), back_inserter(m_tree[index]));
- int si = int(m_tree[i].size());
- int sj=int(m_tree[j].size());
- int p=0;
- int q=0;
- while(p<si && q<sj){
- if(m_tree[i][p][0]<m_tree[j][q][0]){
- m_tree[index].push_back({m_tree[i][p][0], p, q});
- ++p;
- }else if(m_tree[i][p][0]>m_tree[j][q][0]){
- m_tree[index].push_back({m_tree[j][q][0], p, q});
- ++q;
- }else {
- m_tree[index].push_back({m_tree[i][p][0], p, q});
- ++p;
- }
- }
- while(p<si){
- m_tree[index].push_back({m_tree[i][p][0], p, q});
- ++p;
- }
- while(q<sj){
- m_tree[index].push_back({m_tree[j][q][0], p, q});
- ++q;
- }
- }
- void build(int index, int left, int right, vector<int>&a){
- if(left==right){
- vector<int> begin = {a[left],0,0};
- m_tree[index].push_back(begin);
- }else{
- int mid= (left+right)/2;
- build(index+ 1, left, mid, a); // for 0 inddexm it will be 2*index + 1
- build(index + (2*(mid-left+1)), mid+1, right, a);// for 0 inddexm it will be 2*index + 2
- combine(index+ 1, index + (2*(mid-left+1)) , index);
- }
- }
- int query_internal(int root, int tl, int tr, int left, int right, int mini){
- int size = int(m_tree[root].size());
- if(left > right) return 0;
- if(mini >= size) return 0;
- if(tl==left && tr ==right){
- return (size-mini);
- }
- int mid = (tl+tr)/2;
- int lefty = query_internal(root + 1, tl, mid, left, min(mid,right), m_tree[root][mini][1]);
- int righty = query_internal(root + (2*(mid-tl+1)), mid+1, tr, max(mid+1,left), right, m_tree[root][mini][2]);
- return lefty+righty;
- }
- public:
- SegmentTree1(vector<int>& a){
- n=int(a.size());
- m_tree.resize(2*n);
- build(1,0,n-1,a); // index, left, right, input vector // for 0 inddexm it will (0,0,n-1,a)
- }
- int query(int left, int right, int val){
- int mid = (n-1)/2;
- vector<int> temporary(n);
- for(int i=0;i<n;i++) temporary[i]=m_tree[1][i][0];
- int value =static_cast<int>(upper_bound(temporary.begin(), temporary.end(), val) - temporary.begin());
- if(value==temporary.size()){
- return 0;
- }
- int lefty = query_internal(1+1, 0, mid, left, min(mid,right), m_tree[1][value][1]);
- int righty = query_internal(1 + (2*(mid-0+1)), mid+1, n-1, max(left, mid+1), right, m_tree[1][value][2]);
- return lefty+righty;
- }
- };
- void solve(int testCase){
- int n;
- cin>>n;
- vector<int> a(n);
- for(int i=0;i<n;i++) cin>>a[i];
- int q;
- cin>>q;
- SegmentTree1 segTree(a);
- for(int i=0;i<q;i++){
- int l,r,x;
- cin>>l>>r>>x;
- if(n==1){
- if(x<a[0]){
- cout<<"1\n";
- }else cout<<"0\n";
- }else{
- int value = segTree.query(l - 1, r -1, x);
- cout<<value<<endl;
- }
- }
- }
- signed main(){
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- int t=1;
- int k=1;
- while(k<=t){
- solve(k);
- k++;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment