zoukankan      html  css  js  c++  java
  • 【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

    Sample Output

    1825
    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
    ",(x*tmp.k+tmp.b)%P);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    在线教育项目-day10【微服务简单概念】
    在线教育项目-day10【删除小节视频】
    在线教育项目-day09【添加小节上传视频前端】
    【面试】足够应付面试的Spring事务源码阅读梳理(建议珍藏)
    【面试】Spring事务面试考点吐血整理(建议珍藏)
    【面试】我是如何在面试别人Spring事务时“套路”对方的
    爸爸又给Spring MVC生了个弟弟叫Spring WebFlux
    JVM上的响应式流 — Reactor简介
    我是如何在毕业不久只用1年就升为开发组长的
    JVM平台上的响应式流(Reactive Streams)规范
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7671055.html
Copyright © 2011-2022 走看看