题库6656
题意不再详讲,一开始以为是算期望的一道题,结果发现想错了
和本题相关的算法有:
输入输出外挂(适用于大量输入输出,加快速度)、费马小定理求逆元、前缀和
输入输出外挂模板:
int Scan() { //输入外挂
int res = 0, flag = 0;
char ch;
if((ch = getchar()) == '-') flag = 1;
else if(ch >= '0' && ch <= '9') res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9')
res = res * 10 + (ch - '0');
return flag ? -res : res;
}
void Out(int a) { //输出外挂
if(a < 0) { putchar('-'); a = -a; }
if(a >= 10) Out(a / 10);
putchar(a % 10 + '0');
费马小定理模板
inline int Pow(int x,int y,int p){
int res=1;
while(y){
if(y&1)
res=(1LL*res*x)%p;
y>>=1;
x=(1LL*x*x)%p;
}return res;
}
前缀和这里就不贴代码了
直接给ac代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans[500005],nn[500005],r[500005],s[500005],x[500005],a[500005];
ll mod = 1000000007;
//输入外挂
ll readll() {
ll x = 0, w = 1;
char ch = 0;
while (ch < '0' || ch > '9') {
if (ch == '-') w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + (ch - '0');
ch = getchar();
}
return x * w;
}
//费马小
ll pow_mod(ll x, ll n){
ll res=1;
while(n>0){
if(n&1)res=res*x%mod;
x=x*x%mod;
n>>=1;
}
return res;
}
int main(){
ll t,n,q;
while(~scanf("%lld",&t)){
while(t--){
n=readll();
q=readll();
for(int i = 1;i <= n;i++){
r[i]=readll();
s[i]=readll();
x[i]=readll();
a[i]=readll();
}
ans[0] = ans[1] = 0;
nn[0] = nn[1] = 0;
for(int i = 1;i <= n;i++){
ll num = a[i] * r[i] + (s[i] - r[i]) * (a[i] + ans[i] - ans[x[i]] + mod) % mod;
num = (num + mod) % mod;
nn[i+1] = num * pow_mod(r[i],mod-2) % mod;
ans[i+1] = ans[i] + nn[i+1];
ans[i+1] %= mod;
}
//for(int i = 1;i <= n;i++){
// printf("%d-----------------\n",ans[i]);
// anss += ans[i];
//}
//printf("%d----------------\n",anss);
ll l,r;
for(int i = 0;i < q;i++){
scanf("%lld%lld",&l,&r);
printf("%lld\n",(ans[r] - ans[l] + mod) % mod);
}
}
}
return 0;
}