#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
//mt19937 mrand(random_device{}());
const ll mod=1000000007;
//int rnd(int x) { return mrand() % x;}
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int gcd(int a,int b) { return b?gcd(b,a%b):a;}
// head
const int N=5e5+5;
#define INF 0x3f3f3f3f
template<class T> inline void read(T &x) {
x=0; int c=getchar(),f=1;
for (;!isdigit(c);c=getchar()) if (c==45) f=-1;
for (;isdigit(c);c=getchar()) (x*=10)+=f*(c-'0');
}
int a[N],b[N],next_a[N];
ll pref_a[N];
pair<ll,ll> nd[N*4];
inline pair<ll,ll> merge(pair<ll,ll> nd_1,pair<ll,ll> nd_2) {
return {(nd_1.fi*nd_2.fi)%mod,(nd_2.fi*nd_1.se+nd_2.se)%mod};
}
void build(int p,int l,int r) {
if (l==r) {
if (b[l]==1) nd[p]={1LL,1LL*a[l]};
else nd[p]={1LL*b[l],0LL};
return;
}
int md=(l+r)>>1;
build(p+p,l,md);
build(p+p+1,md+1,r);
nd[p]=merge(nd[p+p],nd[p+p+1]);
}
pair<ll,ll> query(int p,int l,int r,int tl,int tr) {
if (tl==l&&tr==r) return nd[p];
else {
int md=(l+r)>>1;
if (tr<=md) return query(p+p,l,md,tl,tr);
else if (tl>md) return query(p+p+1,md+1,r,tl,tr);
else return merge(query(p+p,l,md,tl,md),query(p+p+1,md+1,r,md+1,tr));
}
}
int main() {
int n,q;
scanf("%d%d",&n,&q);
VI bs;
pref_a[0]=0;
rep(i,1,n+1) {
scanf("%d%d",&a[i],&b[i]);
pref_a[i]=pref_a[i-1]+(b[i]==1?a[i]:0);
if (b[i]>1) bs.pb(i);
}
next_a[n+1]=n+1;
per(i,1,n+1) next_a[i]=a[i]>0?i:next_a[i+1];
build(1,1,n);
auto res=[&](ll v,int tl,int tr)->ll{
if (tl>tr) return v%mod;
pair<ll,ll> f=query(1,1,n,tl,tr);
return (1LL*f.fi*(v%mod)%mod+f.se)%mod;
};
rep(i,0,q) {
int x,l,r;
scanf("%d%d%d",&x,&l,&r);
ll val=x;
int ptr=l;
while (ptr<r) {
if (val==0) {
int next_a_ptr=next_a[ptr+1];
if (next_a_ptr>r) break;
val=a[next_a_ptr];
ptr=next_a_ptr;
continue;
}
auto it=upper_bound(all(bs),ptr);
int next_b_ptr=(it==bs.end()||*it>r)?r+1:*it;
if (next_b_ptr>r) {
val+=(pref_a[r]-pref_a[ptr]);
val%=mod;
break;
}
val+=(pref_a[next_b_ptr-1]-pref_a[ptr]);
if (val>=mod) {
val=res(val,next_b_ptr,r);
break;
}
val=max(val+(1LL*a[next_b_ptr]),val*(1LL*b[next_b_ptr]));
ptr=next_b_ptr;
if (val>=mod) {
val=res(val,ptr+1,r);
break;
}
}
val%=mod;
printf("%lld\n",val);
}
}
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 | #include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef vector<int> VI; typedef long long ll; typedef pair<int,int> PII; typedef double db; //mt19937 mrand(random_device{}()); const ll mod=1000000007; //int rnd(int x) { return mrand() % x;} ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} int gcd(int a,int b) { return b?gcd(b,a%b):a;} // head const int N=5e5+5; #define INF 0x3f3f3f3f template<class T> inline void read(T &x) { x=0; int c=getchar(),f=1; for (;!isdigit(c);c=getchar()) if (c==45) f=-1; for (;isdigit(c);c=getchar()) (x*=10)+=f*(c-'0'); } int a[N],b[N],next_a[N]; ll pref_a[N]; pair<ll,ll> nd[N*4]; inline pair<ll,ll> merge(pair<ll,ll> nd_1,pair<ll,ll> nd_2) { return {(nd_1.fi*nd_2.fi)%mod,(nd_2.fi*nd_1.se+nd_2.se)%mod}; } void build(int p,int l,int r) { if (l==r) { if (b[l]==1) nd[p]={1LL,1LL*a[l]}; else nd[p]={1LL*b[l],0LL}; return; } int md=(l+r)>>1; build(p+p,l,md); build(p+p+1,md+1,r); nd[p]=merge(nd[p+p],nd[p+p+1]); } pair<ll,ll> query(int p,int l,int r,int tl,int tr) { if (tl==l&&tr==r) return nd[p]; else { int md=(l+r)>>1; if (tr<=md) return query(p+p,l,md,tl,tr); else if (tl>md) return query(p+p+1,md+1,r,tl,tr); else return merge(query(p+p,l,md,tl,md),query(p+p+1,md+1,r,md+1,tr)); } } int main() { int n,q; scanf("%d%d",&n,&q); VI bs; pref_a[0]=0; rep(i,1,n+1) { scanf("%d%d",&a[i],&b[i]); pref_a[i]=pref_a[i-1]+(b[i]==1?a[i]:0); if (b[i]>1) bs.pb(i); } next_a[n+1]=n+1; per(i,1,n+1) next_a[i]=a[i]>0?i:next_a[i+1]; build(1,1,n); auto res=[&](ll v,int tl,int tr)->ll{ if (tl>tr) return v%mod; pair<ll,ll> f=query(1,1,n,tl,tr); return (1LL*f.fi*(v%mod)%mod+f.se)%mod; }; rep(i,0,q) { int x,l,r; scanf("%d%d%d",&x,&l,&r); ll val=x; int ptr=l; while (ptr<r) { if (val==0) { int next_a_ptr=next_a[ptr+1]; if (next_a_ptr>r) break; val=a[next_a_ptr]; ptr=next_a_ptr; continue; } auto it=upper_bound(all(bs),ptr); int next_b_ptr=(it==bs.end()||*it>r)?r+1:*it; if (next_b_ptr>r) { val+=(pref_a[r]-pref_a[ptr]); val%=mod; break; } val+=(pref_a[next_b_ptr-1]-pref_a[ptr]); if (val>=mod) { val=res(val,next_b_ptr,r); break; } val=max(val+(1LL*a[next_b_ptr]),val*(1LL*b[next_b_ptr])); ptr=next_b_ptr; if (val>=mod) { val=res(val,ptr+1,r); break; } } val%=mod; printf("%lld\n",val); } } |
English