【BZOJ4499】线性函数 线段树
【BZOJ4499】线性函数
Description
小C最近在学习线性函数,线性函数可以表示为:f(x) = kx + b。现在小C面前有n个线性函数fi(x)=kix+bi ,他对这n个线性函数执行m次操作,每次可以:
1.M i K B 代表把第i个线性函数改为:fi(x)=kx+b 。
2.Q l r x 返回fr(fr-1(...fl(x))) mod 10^9+7 。
Input
第一行两个整数n, m (1 <= n, m <= 200,000)。
接下来n行,每行两个整数ki, bi。
接下来m行,每行的格式为M i K B或者Q l r x。
Output
对于每个Q操作,输出一行答案。
Sample Input
5 5
4 2
3 6
5 7
2 6
7 5
Q 1 5 1
Q 3 3 2
M 3 10 6
Q 1 4 3
Q 3 4 4
4 2
3 6
5 7
2 6
7 5
Q 1 5 1
Q 3 3 2
M 3 10 6
Q 1 4 3
Q 3 4 4
Sample Output
1825
17
978
98
17
978
98
HINT
1 <= n, m <= 200,000,0 <= k, b, x < 1000,000,007
题解:这个式子显然是可以用线段树维护的。
维护区间k的乘积sk,区间的那个式子的值sb,则合并时sb=sb1*sk2+sb2,sk=sk1*sk2。答案就是x*sk+sb。
#include <cstdio> #include <cstring> #include <iostream> #define lson x<<1 #define rson x<<1|1 using namespace std; typedef long long ll; const ll P=1000000007; const int maxn=200010; int n,m; ll B[maxn],K[maxn]; char str[5]; struct node { ll b,k; node() {} node(ll x,ll y) {b=x,k=y;} node operator + (const node &a) const {return node((b*a.k+a.b)%P,k*a.k%P);} }s[maxn<<2]; void build(int l,int r,int x) { if(l==r) { s[x]=node(B[l],K[l]); return ; } int mid=(l+r)>>1; build(l,mid,lson),build(mid+1,r,rson); s[x]=s[lson]+s[rson]; } void updata(int l,int r,int x,int a) { if(l==r) { s[x]=node(B[l],K[l]); return ; } int mid=(l+r)>>1; if(a<=mid) updata(l,mid,lson,a); else updata(mid+1,r,rson,a); s[x]=s[lson]+s[rson]; } node query(int l,int r,int x,int a,int b) { if(a<=l&&r<=b) return s[x]; int mid=(l+r)>>1; if(b<=mid) return query(l,mid,lson,a,b); if(a>mid) return query(mid+1,r,rson,a,b); return query(l,mid,lson,a,b)+query(mid+1,r,rson,a,b); } inline int rd() { int ret=0,f=1; char gc=getchar(); while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();} while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret*f; } int main() { int i,a,b; ll x; n=rd(),m=rd(); for(i=1;i<=n;i++) K[i]=rd(),B[i]=rd(); build(1,n,1); for(i=1;i<=m;i++) { scanf("%s",str); if(str[0]=='M') { a=rd(),K[a]=rd(),B[a]=rd(); updata(1,n,1,a); } else { a=rd(),b=rd(),x=rd(); node tmp=query(1,n,1,a,b); printf("%lld\n",(x*tmp.k+tmp.b)%P); } } return 0; }
| 欢迎来原网站坐坐! >原文链接<