//Author: Kevin
#include<bits/stdc++.h>
//#pragma GCC optimize("O2")
using namespace std;
#define pb emplace_back
#define mp make_pair
#define ALL(x) (x).begin(),(x).end()
#define rALL(x) (x).rbegin(),(x).rend()
#define srt(x) sort(ALL(x))
#define rev(x) reverse(ALL(x))
#define rsrt(x) sort(rALL(x))
#define sz(x) (int)(x.size())
#define inf 0x3f3f3f3f
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using ll=long long;
using ull=unsigned long long;
using pii=pair<int,int>;
using i128=__int128_t;
void die(string S){puts(S.c_str());exit(0);}
#define ls (x<<1)
#define rs (ls|1)
const ll mod=1e9+7;
int n,q;
ll a[500500],b[500500];
ll x[100100];
int l[100100],r[100100];
ll sa[500500];
struct info_t
{
ll m,a;
}seg[500500<<2];
info_t merge(const info_t &A,const info_t &B)
{
return {A.m*B.m%mod,(A.a*B.m+B.a)%mod};
}
void build(int x,int l,int r)
{
if(l==r)
{
if(b[l]<=1) seg[x]={1,a[l]};
else seg[x]={b[l],0};
return ;
}
int mid=(l+r)/2;
build(ls,l,mid);
build(rs,mid+1,r);
seg[x]=merge(seg[ls],seg[rs]);
}
info_t query(int x,int l,int r,int ql,int qr)
{
if(ql==l&&r==qr) return seg[x];
int mid=(l+r)/2;
if(qr<=mid) return query(ls,l,mid,ql,qr);
if(ql>mid) return query(rs,mid+1,r,ql,qr);
return merge(query(ls,l,mid,ql,mid),query(rs,mid+1,r,mid+1,qr));
}
int nxt[500500];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)
cin>>a[i]>>b[i];
for(int i=1;i<=q;i++)
cin>>x[i]>>l[i]>>r[i];
for(int i=1;i<=n;i++)
sa[i]=sa[i-1]+a[i];
build(1,1,n);
nxt[n+1]=n+1;
for(int i=n;i>=1;i--)
if(b[i]>1)
nxt[i]=i;
else
nxt[i]=nxt[i+1];
for(int i=1;i<=q;i++)
{
ll x=::x[i],rx=::x[i];
int p=l[i]+1;
while(nxt[p]<=r[i]&&x<2*mod)
{
x=min(2*mod,x+sa[nxt[p]-1]-sa[p-1]);
rx=(rx+sa[nxt[p]-1]-sa[p-1])%mod;
if(x+a[nxt[p]]>x*b[nxt[p]])
{
x+=a[nxt[p]];
rx=(rx+a[nxt[p]])%mod;
}
else
{
x*=b[nxt[p]];
rx=rx*b[nxt[p]]%mod;
}
x=min(x,2*mod);
p=nxt[p]+1;
}
if(p<=r[i]&&x>=2*mod)
{
auto [mul,add]=query(1,1,n,p,r[i]);
rx=(rx*mul+add)%mod;
}
else
rx=(rx+sa[r[i]]-sa[p-1])%mod;
cout<<rx<<'\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 | //Author: Kevin #include<bits/stdc++.h> //#pragma GCC optimize("O2") using namespace std; #define pb emplace_back #define mp make_pair #define ALL(x) (x).begin(),(x).end() #define rALL(x) (x).rbegin(),(x).rend() #define srt(x) sort(ALL(x)) #define rev(x) reverse(ALL(x)) #define rsrt(x) sort(rALL(x)) #define sz(x) (int)(x.size()) #define inf 0x3f3f3f3f #define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin()) #define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin()) #define uni(v) v.resize(unique(ALL(v))-v.begin()) using ll=long long; using ull=unsigned long long; using pii=pair<int,int>; using i128=__int128_t; void die(string S){puts(S.c_str());exit(0);} #define ls (x<<1) #define rs (ls|1) const ll mod=1e9+7; int n,q; ll a[500500],b[500500]; ll x[100100]; int l[100100],r[100100]; ll sa[500500]; struct info_t { ll m,a; }seg[500500<<2]; info_t merge(const info_t &A,const info_t &B) { return {A.m*B.m%mod,(A.a*B.m+B.a)%mod}; } void build(int x,int l,int r) { if(l==r) { if(b[l]<=1) seg[x]={1,a[l]}; else seg[x]={b[l],0}; return ; } int mid=(l+r)/2; build(ls,l,mid); build(rs,mid+1,r); seg[x]=merge(seg[ls],seg[rs]); } info_t query(int x,int l,int r,int ql,int qr) { if(ql==l&&r==qr) return seg[x]; int mid=(l+r)/2; if(qr<=mid) return query(ls,l,mid,ql,qr); if(ql>mid) return query(rs,mid+1,r,ql,qr); return merge(query(ls,l,mid,ql,mid),query(rs,mid+1,r,mid+1,qr)); } int nxt[500500]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>q; for(int i=1;i<=n;i++) cin>>a[i]>>b[i]; for(int i=1;i<=q;i++) cin>>x[i]>>l[i]>>r[i]; for(int i=1;i<=n;i++) sa[i]=sa[i-1]+a[i]; build(1,1,n); nxt[n+1]=n+1; for(int i=n;i>=1;i--) if(b[i]>1) nxt[i]=i; else nxt[i]=nxt[i+1]; for(int i=1;i<=q;i++) { ll x=::x[i],rx=::x[i]; int p=l[i]+1; while(nxt[p]<=r[i]&&x<2*mod) { x=min(2*mod,x+sa[nxt[p]-1]-sa[p-1]); rx=(rx+sa[nxt[p]-1]-sa[p-1])%mod; if(x+a[nxt[p]]>x*b[nxt[p]]) { x+=a[nxt[p]]; rx=(rx+a[nxt[p]])%mod; } else { x*=b[nxt[p]]; rx=rx*b[nxt[p]]%mod; } x=min(x,2*mod); p=nxt[p]+1; } if(p<=r[i]&&x>=2*mod) { auto [mul,add]=query(1,1,n,p,r[i]); rx=(rx*mul+add)%mod; } else rx=(rx+sa[r[i]]-sa[p-1])%mod; cout<<rx<<'\n'; } return 0; } |
English