zoukankan      html  css  js  c++  java
  • 一次函数(好难的一次函数)

    一次函数


    (fx.c/cpp/pas)


    【题目描述】


    fqk 退役后开始补习文化课啦, 于是他打开了数学必修一开始复习
    函数, 他回想起了一次函数都是 b kx x f   ) ( 的形式, 现在他给了你 n 个
    一次函数


    i i i
    b x k x f   ) ( , 然后将给你 m 个操作, 操作将以如下格式给出:
    M . 1 i k b ,把第 i 个函数改为 b kx x f i   ) ( 。
    Q . 2 l r x ,询问 ))) ( (... (
    1
    x f f f
    l r r 
    mod 1000000007 的值。


    【输入格式】


    第一行两个整数 n , m ,代表一次函数的数量和操作的数量。
    接下来 n 行,每行两个整数,表示
    i
    k ,
    i
    b 。
    接下来 m 行,每行的格式为 M i k b 或 Q l r x 。


    【输出格式】


    对于每个操作 Q ,输出一行表示答案。


    【输入样例】


    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


    【输出样例】


    1825
    17
    978
    98


    【数据范围】


    对于 % 30 的数据, 1000 ,  m n 。
    对于 % 100 的数据, 1000000007 , , , 200000 ,   x b k m n 。


    【时空限制】


    对于每个测试点,时间限制为 s 2 ,空间限制为 MB 512 。

    思路:

      刚开始先看数据范围(好习惯)

      发现这是个暴力过不了的题

      于是开始边推公式边码代码

      推了一个小时公式终于推了出来

      但是爆零了!

      因为这个题里有一个mod条件

      大于这个mod值就必须被mod

      但是我的公式里有用到除法

      所以就被整数不能被零除这种错误给RE了

      最后还是ylf大神讲的思路

      正解是线段树

      题目里的操作M和Q正符合线段树的单点修改和区间查询

      所以我开始着手写线段树

      线段树要维护两个值

      hyxzc告诉我要用数组比结构体要快

      但是我还是用的结构体

      在维护线段树的值得时候

      维护k和b

      具体是这样维护的

      k2*(k1*x+b1)+b2

      可以化成这种形式

      k2*k1*x+k2*b1+b2

      这样我们就可以得到新的值

      k3=k2*k1,b3=k2*b1+b2

      k3,b3就是一个小区间的值

      这样我们就可以推出l到r的k于b

      来,上代码:

    #include<cmath>
    #include<cstdio>
    #include<iostream>
    
    #define mod 1000000007
    
    using namespace std;
    
    struct node {
        long long int l,r,kl,b;
    };
    struct node tree[10000001],cur;
    
    long long int n,m,jkl,ll,rr,dis;
    
    char ch,ch1;
    
    void qread(long long int &x)
    {
        x=0,jkl=1;ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-') jkl=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+(int)(ch-'0');ch=getchar();}
        x*=jkl;
    }
    
    void tree_up(long long int k)
    {
        tree[k].kl=(tree[k<<1].kl*tree[k<<1|1].kl)%mod;
        tree[k].b=((tree[k<<1].b*tree[k<<1|1].kl)%mod+tree[k<<1|1].b)%mod;
    }
    
    void tree_build(long long int k,long long int l,long long int r)
    {
        tree[k].l=l,tree[k].r=r;
        if(l==r)
        {
            qread(tree[k].kl),qread(tree[k].b);
            return ;
        }
        long long int mid=(l+r)>>1;
        tree_build(k<<1,l,mid),tree_build(k<<1|1,mid+1,r);
        tree_up(k);
    }
    
    void tree_change(long long int k,long long int to,long long int nk,long long int nb)
    {
        if(tree[k].l==tree[k].r&&tree[k].l==to)
        {
            tree[k].kl=nk,tree[k].b=nb;
            return ;
        }
        long long int mid=(tree[k].l+tree[k].r)>>1;
        if(to<=mid) tree_change(k<<1,to,nk,nb);
        else tree_change(k<<1|1,to,nk,nb);
        tree_up(k);
    }
    
    struct node tree_sum(long long int k,long long int l,long long int r)
    {
        if(l==tree[k].l&&r==tree[k].r) return tree[k];
        long long int mid=(tree[k].l+tree[k].r)>>1;
        if(l>mid) return tree_sum(k<<1|1,l,r);
        else if(r<=mid) return tree_sum(k<<1,l,r);
        else
        {
            struct node now1,now2;
            now1=tree_sum(k<<1,l,mid);
            now2=tree_sum(k<<1|1,mid+1,r);
            now1.b=((now2.kl*now1.b)%mod+now2.b)%mod;
            now1.kl=(now1.kl*now2.kl)%mod;
            return now1;
        }
    }
    
    int main()
    {
        qread(n),qread(m);
        tree_build(1,1,n);
        for(long long int i=1;i<=m;i++)
        {
            //scanf("%c %lld%lld%lld",&ch1,&ll,&rr,&dis);
            scanf("%c ",&ch1);
            qread(ll),qread(rr),qread(dis);
            if(ch1=='M') tree_change(1,ll,rr,dis);
            else
            {
                cur=tree_sum(1,ll,rr);
                dis=((dis*cur.kl)%mod+cur.b)%mod;
                cout<<dis<<endl;
            }
        }
        return 0;
    }

      附,祭奠我那逝去的公式=.=

      :

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    
    #define mod 1000000007
    
    using namespace std;
    
    struct node {
        long long int k,b;
    };
    struct node function[2000002];
    
    long long int n,m,jkl,l,r,dis,cur,kol;
    long long int sumk[2000002],sumb[2000002],sumbb[2000002];
    
    char ch,ch1;
    
    bool ok=false;
    
    void qread(long long int &x)
    {
        x=0,jkl=1;ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-') jkl=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+(int)(ch-'0');ch=getchar();}
        x*=jkl;
    }
    
    void change()
    {
        for(long long int j=1;j<=n;j++)
        {
            sumk[j]=(sumk[j-1]*function[j].k)%mod;
            //sumb[j]=((sumb[i-1]*function[i].k)%mod+function[i].b)%mod;
        }
        for(long long int j=1;j<=n;j++)
        {
            sumb[j]=(((function[j].b*sumk[n])%mod)/sumk[j])%mod;
            sumbb[j]=sumbb[j-1]+sumb[j];
        }
        ok=false;
    }
    
    int main()
    {
        sumk[0]=1;
        qread(n),qread(m);
        sumk[n+1]=1;
        for(long long int i=1;i<=n;i++)
        {
            qread(function[i].k),qread(function[i].b);
            sumk[i]=(sumk[i-1]*function[i].k)%mod;
            //sumb[i]=((sumb[i-1]*function[i].k)%mod+function[i].b)%mod;
            sumb[i]=function[i].b;
        }
        for(long long int i=1;i<=n;i++)
        {
            sumb[i]=(((sumb[i]*sumk[n])%mod)/sumk[i])%mod;
            sumbb[i]=sumbb[i-1]+sumb[i];
        }
        for(long long int i=1;i<=m;i++)
        {
            scanf("%c",&ch1),qread(l),qread(r),qread(dis);
            //cout<<l<<" "<<r<<" "<<dis<<" "<<endl;
            if(ch1=='M')
            {
                function[l].k=r,function[l].b=dis,ok=true;
                /*for(long long int j=1;j<=n;j++)
                {
                    sumk[j]=(sumk[j-1]*function[j].k)%mod;
                    //sumb[j]=((sumb[i-1]*function[i].k)%mod+function[i].b)%mod;
                }
                for(long long int j=1;j<=n;j++)
                {
                    sumb[j]=(((function[j].b*sumk[n])%mod)/sumk[j])%mod;
                    sumbb[j]=sumbb[j-1]+sumb[j];
                }*/
            }
            else
            {
                if(ok) change();
                cur=dis;
                cur=((cur*sumk[r]%mod)/sumk[l-1])%mod;
                //cout<<cur<<endl;
                //kol=(sumb[r]-sumb[l-1]);
                /*if(sumk[n]/sumk[r]==0){
                    cout<<n<<" "<<r<<endl;
                    cout<<sumk[n]<<" "<<sumk[r]<<endl;
                    system("pause");
                }*/
                kol=((sumbb[r]-sumbb[l-1])/(sumk[n]/sumk[r]));
                //cout<<n<<" "<<r<<endl;
                //cout<<sumk[n]<<" "<<sumk[r]<<endl;
                //cout<<sumk[n]/sumk[r]<<endl<<(sumbb[r]-sumbb[l-1])<<endl<<kol<<endl;
                cur=(cur+kol)%mod;
                cout<<cur<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    python 基于gevent协程实现socket并发
    python asyncio
    python 池 协程
    python
    python 守护进程
    python 线程 threading模块
    python 安装Django失败处理
    python 队列
    python 锁
    继承,抽象类,多态,封装
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6048723.html
Copyright © 2011-2022 走看看