#include <iostream>
#include <vector>
using namespace std;
const int stala=5e5+10;
long long mod=1e9+7;
long long tab[stala][2];
int pierwsza_dodatnia[stala];
long long pref[stala];
int next_mnozenie[stala];
long long dp[stala][20];
long long multiple[stala][20];
long long suma_pref(int ind,int ind2)
{
return pref[ind2]-pref[ind-1];
}
long long zwroc(long long pocz,int ind,int ind2)
{
if(pocz==0){
pocz=mod;
}
long long war=((pocz-(long long)1)*multiple[ind][ind2])%mod;
return (war+dp[ind][ind2])%mod;
}
void prep(int ile)
{
for(int i=1;i<=ile;i++){
multiple[i][0]=1;
if(tab[i][1]>=2){
dp[i][0]=tab[i][1];
multiple[i][0]=tab[i][1];
}
else{
dp[i][0]=(tab[i][0]+1)%mod;
}
}
for(int j=1;j<=19;j++){
for(int i=1;i<=ile-(1<<j)+1;i++){
dp[i][j]=zwroc(dp[i][j-1],i+(1<<(j-1)),j-1);
multiple[i][j]=(multiple[i][j-1]*multiple[i+(1<<(j-1))][j-1])%mod;
}
}
}
long long daj_wynik(int ind,int ind2,long long pocz)
{
for(int i=19;i>=0;i--){
if(ind+(1<<i)<=ind2+1){
pocz=zwroc(pocz,ind,i);
ind+=(1<<i);
}
}
return pocz;
}
long long query(long long start,int ind,int ind2)
{
if(start==0){
ind=pierwsza_dodatnia[ind];
if(ind==ind2){
return tab[ind][0];
}
else if(ind>ind2){
return 0;
}
start=tab[ind][0];
ind++;
}
while(true){
int nxt=min(next_mnozenie[ind],ind2);
if(ind<=nxt-1){
start+=suma_pref(ind,nxt-1);
}
if(start>mod){
ind=nxt;
start%=mod;
break;
}
start=max(start+tab[nxt][0],start*tab[nxt][1]);
if(nxt==ind2){
return start%mod;
}
if(start>mod){
ind=nxt+1;
start%=mod;
break;
}
ind=nxt+1;
}
return daj_wynik(ind,ind2,start);
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int ile,q;
cin>>ile>>q;
for(int i=1;i<=ile;i++){
cin>>tab[i][0]>>tab[i][1];
}
pierwsza_dodatnia[ile+1]=1e9;
next_mnozenie[ile+1]=1e9;
for(int i=ile;i>=1;i--){
pierwsza_dodatnia[i]=pierwsza_dodatnia[i+1];
next_mnozenie[i]=next_mnozenie[i+1];
if(tab[i][0]>0){
pierwsza_dodatnia[i]=i;
}
if(tab[i][1]>=2){
next_mnozenie[i]=i;
}
}
for(int i=1;i<=ile;i++){
pref[i]=pref[i-1]+tab[i][0];
}
prep(ile);
for(int i=1;i<=q;i++){
long long start;
int x,y;
cin>>start>>x>>y;
cout<<query(start,x+1,y)<<"\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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #include <iostream> #include <vector> using namespace std; const int stala=5e5+10; long long mod=1e9+7; long long tab[stala][2]; int pierwsza_dodatnia[stala]; long long pref[stala]; int next_mnozenie[stala]; long long dp[stala][20]; long long multiple[stala][20]; long long suma_pref(int ind,int ind2) { return pref[ind2]-pref[ind-1]; } long long zwroc(long long pocz,int ind,int ind2) { if(pocz==0){ pocz=mod; } long long war=((pocz-(long long)1)*multiple[ind][ind2])%mod; return (war+dp[ind][ind2])%mod; } void prep(int ile) { for(int i=1;i<=ile;i++){ multiple[i][0]=1; if(tab[i][1]>=2){ dp[i][0]=tab[i][1]; multiple[i][0]=tab[i][1]; } else{ dp[i][0]=(tab[i][0]+1)%mod; } } for(int j=1;j<=19;j++){ for(int i=1;i<=ile-(1<<j)+1;i++){ dp[i][j]=zwroc(dp[i][j-1],i+(1<<(j-1)),j-1); multiple[i][j]=(multiple[i][j-1]*multiple[i+(1<<(j-1))][j-1])%mod; } } } long long daj_wynik(int ind,int ind2,long long pocz) { for(int i=19;i>=0;i--){ if(ind+(1<<i)<=ind2+1){ pocz=zwroc(pocz,ind,i); ind+=(1<<i); } } return pocz; } long long query(long long start,int ind,int ind2) { if(start==0){ ind=pierwsza_dodatnia[ind]; if(ind==ind2){ return tab[ind][0]; } else if(ind>ind2){ return 0; } start=tab[ind][0]; ind++; } while(true){ int nxt=min(next_mnozenie[ind],ind2); if(ind<=nxt-1){ start+=suma_pref(ind,nxt-1); } if(start>mod){ ind=nxt; start%=mod; break; } start=max(start+tab[nxt][0],start*tab[nxt][1]); if(nxt==ind2){ return start%mod; } if(start>mod){ ind=nxt+1; start%=mod; break; } ind=nxt+1; } return daj_wynik(ind,ind2,start); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int ile,q; cin>>ile>>q; for(int i=1;i<=ile;i++){ cin>>tab[i][0]>>tab[i][1]; } pierwsza_dodatnia[ile+1]=1e9; next_mnozenie[ile+1]=1e9; for(int i=ile;i>=1;i--){ pierwsza_dodatnia[i]=pierwsza_dodatnia[i+1]; next_mnozenie[i]=next_mnozenie[i+1]; if(tab[i][0]>0){ pierwsza_dodatnia[i]=i; } if(tab[i][1]>=2){ next_mnozenie[i]=i; } } for(int i=1;i<=ile;i++){ pref[i]=pref[i-1]+tab[i][0]; } prep(ile); for(int i=1;i<=q;i++){ long long start; int x,y; cin>>start>>x>>y; cout<<query(start,x+1,y)<<"\n"; } return 0; } |
English