#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
typedef long long ll;
const ll M = 1000LL*1000LL*1000LL+7LL;
class GraMobilna{
public:
vector< pair<int, int> > events;
vector<int> tree;
vector<int> multi_prefix;
vector<int> nb_zer;
int n, S;
GraMobilna(int n = 0){ init(n); }
void init(int n_){
n = n_;
S = 1;
while( S <= (n+2) ) S*=2;
events.assign(n+1, {0, 1});
nb_zer.assign(S+1, 0);
tree.assign(2*S, 0);
multi_prefix.assign(n+1, 1);
}
void add_event(int i, int a, int b){
assert(1 <= i && i <= n);
events[i] = {a, b};
if( b > 1 ) tree[i+S] = 0;
else tree[i+S] = a;
}
pair<int,int> node_tree_interval(int v) {
int h = 31 - __builtin_clz(v);
int ls = 1 << h;
int id = v - ls;
int len = S >> h;
int l = id * len;
int r = l + len - 1;
return {l, r};
}
int power(long long a, long long e){
long long r = 1;
while (e > 0) {
if (e & 1) r = (r * a) % M;
a = (a * a) % M;
e >>= 1;
}
return r%M;
}
int multi_interval(int l, int r){
if( l == 0 ){
if(nb_zer[r] > 0 ) return 0;
return multi_prefix[r];
}
if( nb_zer[r] - nb_zer[l-1] > 0 ) return 0;
ll res = multi_prefix[r];
return ( (ll)res*(ll)power(multi_prefix[l-1], M-2) )%M;
}
int is_multi(int l){
return (events[l-S].s > 1 );
}
int merge_values(ll v1, ll v2, pair<int, int> p2){
int res = ((ll)v1*(ll)multi_interval(p2.f, p2.s)+(ll)v2 )%M;
return res;
}
int merge_intervals(int v_l, int v_r){
auto ivr = node_tree_interval(v_r);
return merge_values( tree[v_l], tree[v_r], ivr );
}
void build_tree(){
for(int i = S-1; i >= 1; i--){
tree[i] = merge_intervals(2*i, 2*i+1);
}
}
int sum_mul_interval_ins(int p_p, int k_p, int v, int p_b, int k_b){
if( p_b > k_p || k_b < p_p ) return -1;
if( p_p <= p_b && k_b <= k_p ) return tree[v];
int s = (p_b+k_b)/2;
int resl = sum_mul_interval_ins(p_p, k_p, 2*v, p_b, s);
int resr = sum_mul_interval_ins(p_p, k_p, 2*v+1, s+1, k_b);
//cout << "v " << v << ": " << resl << " " << resr << endl;
//cout << "value " << merge_values(resl, resr, {s+1, min(k_b,k_p)} ) << endl;
if( resl == -1 ) return resr;
if( resr == -1 ) return resl;
return merge_values(resl, resr, {s+1, min(k_b,k_p)} );
}
int sum_mul_interval(int p, int k){
return sum_mul_interval_ins(p, k, 1, 0, S-1);
}
void pre_processing(){
for(int i = 1; i <= n; i++){
nb_zer[i] = nb_zer[i-1];
if( events[i].s % M == 0 ) nb_zer[i]++;
}
for(int i = n+1; i < (int)nb_zer.size(); i++ ) nb_zer[i] = nb_zer[i-1];
for(int i = 1; i <= n; i++) multi_prefix[i] = ( multi_prefix[i-1]*(ll)events[i].s ) %M;
build_tree();
}
void move_left_end_until_only_multiplying(int &l, const int r, ll& res){
while( l <= r ){
if( res <= M ) res = max(res+events[l].f, res*events[l].s);
else return;
l++;
}
}
int query(int l, int r, int x){
ll res = (ll)x;
move_left_end_until_only_multiplying(l, r, res);
if( res >= M ) res %= M;
if( l<=r ) res *= multi_interval(l, r);
if( res >= M ) res %= M;
if( l<=r ) res += sum_mul_interval(l, r);
if( res >= M ) res %= M;
return res;
}
};
void solve(){
int n, q; int a, b; int l, r, x;
cin >> n >> q;
GraMobilna GM(n);
for(int i = 1; i <= n; i++){
cin >> a >> b;
GM.add_event(i, a, b);
}
GM.pre_processing();
for(int i = 1; i <= q; i++){
cin >> x >> l >> r;
l++;
cout << GM.query(l, r, x) << "\n";
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | #include <bits/stdc++.h> using namespace std; #define f first #define s second typedef long long ll; const ll M = 1000LL*1000LL*1000LL+7LL; class GraMobilna{ public: vector< pair<int, int> > events; vector<int> tree; vector<int> multi_prefix; vector<int> nb_zer; int n, S; GraMobilna(int n = 0){ init(n); } void init(int n_){ n = n_; S = 1; while( S <= (n+2) ) S*=2; events.assign(n+1, {0, 1}); nb_zer.assign(S+1, 0); tree.assign(2*S, 0); multi_prefix.assign(n+1, 1); } void add_event(int i, int a, int b){ assert(1 <= i && i <= n); events[i] = {a, b}; if( b > 1 ) tree[i+S] = 0; else tree[i+S] = a; } pair<int,int> node_tree_interval(int v) { int h = 31 - __builtin_clz(v); int ls = 1 << h; int id = v - ls; int len = S >> h; int l = id * len; int r = l + len - 1; return {l, r}; } int power(long long a, long long e){ long long r = 1; while (e > 0) { if (e & 1) r = (r * a) % M; a = (a * a) % M; e >>= 1; } return r%M; } int multi_interval(int l, int r){ if( l == 0 ){ if(nb_zer[r] > 0 ) return 0; return multi_prefix[r]; } if( nb_zer[r] - nb_zer[l-1] > 0 ) return 0; ll res = multi_prefix[r]; return ( (ll)res*(ll)power(multi_prefix[l-1], M-2) )%M; } int is_multi(int l){ return (events[l-S].s > 1 ); } int merge_values(ll v1, ll v2, pair<int, int> p2){ int res = ((ll)v1*(ll)multi_interval(p2.f, p2.s)+(ll)v2 )%M; return res; } int merge_intervals(int v_l, int v_r){ auto ivr = node_tree_interval(v_r); return merge_values( tree[v_l], tree[v_r], ivr ); } void build_tree(){ for(int i = S-1; i >= 1; i--){ tree[i] = merge_intervals(2*i, 2*i+1); } } int sum_mul_interval_ins(int p_p, int k_p, int v, int p_b, int k_b){ if( p_b > k_p || k_b < p_p ) return -1; if( p_p <= p_b && k_b <= k_p ) return tree[v]; int s = (p_b+k_b)/2; int resl = sum_mul_interval_ins(p_p, k_p, 2*v, p_b, s); int resr = sum_mul_interval_ins(p_p, k_p, 2*v+1, s+1, k_b); //cout << "v " << v << ": " << resl << " " << resr << endl; //cout << "value " << merge_values(resl, resr, {s+1, min(k_b,k_p)} ) << endl; if( resl == -1 ) return resr; if( resr == -1 ) return resl; return merge_values(resl, resr, {s+1, min(k_b,k_p)} ); } int sum_mul_interval(int p, int k){ return sum_mul_interval_ins(p, k, 1, 0, S-1); } void pre_processing(){ for(int i = 1; i <= n; i++){ nb_zer[i] = nb_zer[i-1]; if( events[i].s % M == 0 ) nb_zer[i]++; } for(int i = n+1; i < (int)nb_zer.size(); i++ ) nb_zer[i] = nb_zer[i-1]; for(int i = 1; i <= n; i++) multi_prefix[i] = ( multi_prefix[i-1]*(ll)events[i].s ) %M; build_tree(); } void move_left_end_until_only_multiplying(int &l, const int r, ll& res){ while( l <= r ){ if( res <= M ) res = max(res+events[l].f, res*events[l].s); else return; l++; } } int query(int l, int r, int x){ ll res = (ll)x; move_left_end_until_only_multiplying(l, r, res); if( res >= M ) res %= M; if( l<=r ) res *= multi_interval(l, r); if( res >= M ) res %= M; if( l<=r ) res += sum_mul_interval(l, r); if( res >= M ) res %= M; return res; } }; void solve(){ int n, q; int a, b; int l, r, x; cin >> n >> q; GraMobilna GM(n); for(int i = 1; i <= n; i++){ cin >> a >> b; GM.add_event(i, a, b); } GM.pre_processing(); for(int i = 1; i <= q; i++){ cin >> x >> l >> r; l++; cout << GM.query(l, r, x) << "\n"; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); solve(); } |
English