#include "bits/stdc++.h"
#define all(v) (v).begin(), (v).end()
#define st first
#define nd second
#define printv(a) { for(auto u : a) cout<<u<<" "; cout<<"\n"; }
#define debug(x) cerr << #x << " = " << x << '\n';
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using vi = vector<int>;
using si = set<int>;
using mii = map<int,int>;
const ll MOD = 1e9 + 7;
const int MAXN = 500005;
ll sparse[MAXN][20];
ll multi[MAXN][20];
ll sum_pref[MAXN];
ll next_mult[MAXN];
ll tab[MAXN][2];
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n,q;
cin>>n>>q;
for(int i=0;i<n;i++){
ll a,b;
cin>>a>>b;
tab[i][0] = a;
tab[i][1] = b;
sum_pref[i] = (i == 0 ? a : sum_pref[i-1] + a);
sparse[i][0] = (b == 1 ? a : 0);
multi[i][0] = (b == 1 ? 1 : b);
}
int pom = n;
next_mult[n] = n;
for(int i = n-1;i>=0;i--){
if(tab[i][1] != 1) pom = i;
//cout<<" ustawiamy dla "<<i<<" "<<pom<<endl;
next_mult[i] = pom;
}
for(int k=1;k<20;k++){
pom = (1<<(k-1));
for(int i=0;i<n;i++){
if(i + (1<<(k-1)) >= n){
sparse[i][k] = sparse[i][k-1];
multi[i][k] = multi[i][k-1];
continue;
}
sparse[i][k] = sparse[i][k-1] * multi[i + pom][k-1];
sparse[i][k] %= MOD;
sparse[i][k] += sparse[i+pom][k-1];
sparse[i][k] %= MOD;
multi[i][k] = multi[i][k-1] * multi[i+pom][k-1];
multi[i][k] %= MOD;
}
}
while(q--){
ll x;
int a,b;
cin>>x>>a>>b;
b--;
ll wyn = x;
while(wyn < MOD){
if(next_mult[a] > b){
wyn += sum_pref[b] - sum_pref[a-1];
a = b+1;
break;
}
int p = next_mult[a];
//cout<<" wchodzimy z "<<a<<" i idziemy do "<<p<<endl;
wyn += sum_pref[p-1] - sum_pref[a-1];
if(wyn * tab[p][1] > wyn + tab[p][0]) wyn *= tab[p][1];
else wyn += tab[p][0];
a = p+1;
}
//cout<<" uzbieralismy "<<wyn<<" i teraz a i b to "<<a<<" "<<b<<endl;
wyn %= MOD;
int k = 20;
while(k >= 0){
if(a + (1<<k) - 1 > b){
k--;
}else{
//cout<<" mozemy skoczyc i skaczemy o "<<(1<<k)<<endl;
//cout<<" mnozymy razy "<<multi[a][k]<<" i dodajemy "<<sparse[a][k]<<endl;
wyn = wyn * multi[a][k];
wyn %= MOD;
wyn += sparse[a][k];
wyn %= MOD;
a += (1<<k);
}
}
cout<<wyn<<'\n';
}
return 0;
}
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 | #include "bits/stdc++.h" #define all(v) (v).begin(), (v).end() #define st first #define nd second #define printv(a) { for(auto u : a) cout<<u<<" "; cout<<"\n"; } #define debug(x) cerr << #x << " = " << x << '\n'; using namespace std; using ll = long long; using pii = pair<int,int>; using vi = vector<int>; using si = set<int>; using mii = map<int,int>; const ll MOD = 1e9 + 7; const int MAXN = 500005; ll sparse[MAXN][20]; ll multi[MAXN][20]; ll sum_pref[MAXN]; ll next_mult[MAXN]; ll tab[MAXN][2]; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n,q; cin>>n>>q; for(int i=0;i<n;i++){ ll a,b; cin>>a>>b; tab[i][0] = a; tab[i][1] = b; sum_pref[i] = (i == 0 ? a : sum_pref[i-1] + a); sparse[i][0] = (b == 1 ? a : 0); multi[i][0] = (b == 1 ? 1 : b); } int pom = n; next_mult[n] = n; for(int i = n-1;i>=0;i--){ if(tab[i][1] != 1) pom = i; //cout<<" ustawiamy dla "<<i<<" "<<pom<<endl; next_mult[i] = pom; } for(int k=1;k<20;k++){ pom = (1<<(k-1)); for(int i=0;i<n;i++){ if(i + (1<<(k-1)) >= n){ sparse[i][k] = sparse[i][k-1]; multi[i][k] = multi[i][k-1]; continue; } sparse[i][k] = sparse[i][k-1] * multi[i + pom][k-1]; sparse[i][k] %= MOD; sparse[i][k] += sparse[i+pom][k-1]; sparse[i][k] %= MOD; multi[i][k] = multi[i][k-1] * multi[i+pom][k-1]; multi[i][k] %= MOD; } } while(q--){ ll x; int a,b; cin>>x>>a>>b; b--; ll wyn = x; while(wyn < MOD){ if(next_mult[a] > b){ wyn += sum_pref[b] - sum_pref[a-1]; a = b+1; break; } int p = next_mult[a]; //cout<<" wchodzimy z "<<a<<" i idziemy do "<<p<<endl; wyn += sum_pref[p-1] - sum_pref[a-1]; if(wyn * tab[p][1] > wyn + tab[p][0]) wyn *= tab[p][1]; else wyn += tab[p][0]; a = p+1; } //cout<<" uzbieralismy "<<wyn<<" i teraz a i b to "<<a<<" "<<b<<endl; wyn %= MOD; int k = 20; while(k >= 0){ if(a + (1<<k) - 1 > b){ k--; }else{ //cout<<" mozemy skoczyc i skaczemy o "<<(1<<k)<<endl; //cout<<" mnozymy razy "<<multi[a][k]<<" i dodajemy "<<sparse[a][k]<<endl; wyn = wyn * multi[a][k]; wyn %= MOD; wyn += sparse[a][k]; wyn %= MOD; a += (1<<k); } } cout<<wyn<<'\n'; } return 0; } |
English