2020牛客寒假算法基础集训营2 求函数
https://ac.nowcoder.com/acm/contest/3003/J
题意
有 n 个一次函数,第 i 个函数为 fi(x)=ki×x+bi。
有 m 次操作,每次操作为以下二者其一:
• 1 i k b fi(x) 修改为 fi(x)=k×x+b。
• 2 l r 求 fr(fr−1(⋯(fl+1(fl(1)))⋯))。
答案对 10^9+7 取模。
题解
代码
#include<bits/stdc++.h>
using namespace std;
const int N=210000, mod=1e9+7;
struct node
{
int first,second;
};
int n,m,L_tree[N<<2],R_tree[N<<2],k[N];
node ans;
void modify(int des,int k,int b,int L,int R,int root);
void query(int l,int r,int L,int R,int root);
int main()
{
int a,i,b,op;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&k[i]);
for(i=1;i<=n;i++)
{
scanf("%d",&b);
modify(i,k[i],b,1,n,1);
}
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%d",&i,&a,&b);
modify(i,a,b,1,n,1);
}
else
{
ans.first=1;
ans.second=0;
scanf("%d%d",&a,&b);
query(a,b,1,n,1);
printf("%d\n",(ans.first+ans.second)%mod);
}
}
system("pause");
return 0;
}
void modify(int des,int k,int b,int L,int R,int root)
{
if(L==R)
{
L_tree[root]=k;
R_tree[root]=b;
return ;
}
int mid=(L+R)/2;
if(des<=mid) modify(des,k,b,L,mid,root<<1);
else modify(des,k,b,mid+1,R,root<<1|1);
L_tree[root]=1ll*L_tree[root<<1]*L_tree[root<<1|1]%mod;
R_tree[root]=(1ll*R_tree[root<<1]%mod*L_tree[root<<1|1]%mod+R_tree[root<<1|1]%mod)%mod;
}
void query(int l,int r,int L,int R,int root)
{
if(L>=l&&r>=R)
{
ans.first=1ll*ans.first*L_tree[root]%mod;
ans.second=((1ll*ans.second%mod*L_tree[root]%mod)%mod+R_tree[root]%mod)%mod;
return ;
}
int mid=(L+R)/2;
if(l<=mid) query(l,r,L,mid,root<<1);
if(r>mid) query(l,r,mid+1,R,root<<1|1);
}