#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
#define lb lower_bound
using namespace std;
ll a[500007],b[500007];
const ll MOD=1e9+7;
pair<ll,ll>marge(pair<ll,ll>l,pair<ll,ll>p){
return{(l.fi*p.fi)%MOD,(p.fi*l.se+p.se)%MOD};
}
pair<ll,ll>tree[2000007];
void buduj(int n,int p,int k){
if(p==k){
if(b[p]>1) tree[n]={b[p]%MOD,0};else tree[n]={1,a[p]%MOD};
return;
}
int s=(p+k)/2;
buduj(2*n,p,s);
buduj(2*n+1,s+1,k);
tree[n]=marge(tree[2*n],tree[2*n+1]);
}
pair<ll,ll> querry(int n,int pp,int kk,int p,int k){
if(p<=pp&&kk<=k) return tree[n];
if(k<pp||kk<p) return {1,0};
int s=(pp+kk)/2;
return marge(querry(2*n,pp,s,p,k),querry(2*n+1,s+1,kk,p,k));
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n,q;
cin>>n>>q;
vector<int>B,A;
vector<ll>suma(n+1);
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
if(b[i]>=2){B.pb(i);}
if(a[i]>0){A.pb(i);}
suma[i+1]=suma[i]+(b[i]==1?a[i]:0);//suma[i] to po i tej operacji a[i] b[i] to dla i-1 operacji
}
buduj(1,0,n-1);
ll x;int l,r;
while(q--){
cin>>x>>l>>r;
if(x==0){
auto it=lb(A.begin(),A.end(),l);
if(it==A.end()||*it>=r){l=r;}else l=*it;
}
auto it=lb(B.begin(),B.end(),l);
while(l<r&&x<MOD){
int nowy=(it==B.end()||*it>=r?r:*it);
if(l<nowy){x+=suma[nowy]-suma[l];l=nowy;}
if(l<r)
x=max(x+a[l],x*b[l]);l++;it++;
}
x%=MOD;
if(l<r){
pair<ll,ll>wyn=querry(1,0,n-1,l,r-1);
x=(x*wyn.fi+wyn.se)%MOD;
}
cout<<x%MOD<<'\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 | #include<bits/stdc++.h> #define ll long long #define pb push_back #define fi first #define se second #define lb lower_bound using namespace std; ll a[500007],b[500007]; const ll MOD=1e9+7; pair<ll,ll>marge(pair<ll,ll>l,pair<ll,ll>p){ return{(l.fi*p.fi)%MOD,(p.fi*l.se+p.se)%MOD}; } pair<ll,ll>tree[2000007]; void buduj(int n,int p,int k){ if(p==k){ if(b[p]>1) tree[n]={b[p]%MOD,0};else tree[n]={1,a[p]%MOD}; return; } int s=(p+k)/2; buduj(2*n,p,s); buduj(2*n+1,s+1,k); tree[n]=marge(tree[2*n],tree[2*n+1]); } pair<ll,ll> querry(int n,int pp,int kk,int p,int k){ if(p<=pp&&kk<=k) return tree[n]; if(k<pp||kk<p) return {1,0}; int s=(pp+kk)/2; return marge(querry(2*n,pp,s,p,k),querry(2*n+1,s+1,kk,p,k)); } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n,q; cin>>n>>q; vector<int>B,A; vector<ll>suma(n+1); for(int i=0;i<n;i++){ cin>>a[i]>>b[i]; if(b[i]>=2){B.pb(i);} if(a[i]>0){A.pb(i);} suma[i+1]=suma[i]+(b[i]==1?a[i]:0);//suma[i] to po i tej operacji a[i] b[i] to dla i-1 operacji } buduj(1,0,n-1); ll x;int l,r; while(q--){ cin>>x>>l>>r; if(x==0){ auto it=lb(A.begin(),A.end(),l); if(it==A.end()||*it>=r){l=r;}else l=*it; } auto it=lb(B.begin(),B.end(),l); while(l<r&&x<MOD){ int nowy=(it==B.end()||*it>=r?r:*it); if(l<nowy){x+=suma[nowy]-suma[l];l=nowy;} if(l<r) x=max(x+a[l],x*b[l]);l++;it++; } x%=MOD; if(l<r){ pair<ll,ll>wyn=querry(1,0,n-1,l,r-1); x=(x*wyn.fi+wyn.se)%MOD; } cout<<x%MOD<<'\n'; } return 0; } |
English