zoukankan      html  css  js  c++  java
  • LYOI2016 Summer 一次函数 (线段树)

    题目描述

    fqk 退役后开始补习文化课啦,于是他打开了数学必修一开始复习函数,他回想起了一次函数都是 f(x)=kx+b的形式,现在他给了你n个一次函数 fi(x)=kix+b,然后将给你m个操作,操作将以如下格式给出:
        1.M i k b,把第i个函数改为 fi(x)=kx+b。
        2.Q l r x,询问 fr(fr−1(…fl(x))) mod 1000000007的值。

    输入

    第一行两个整数n,m,代表一次函数的数量和操作的数量。
    接下来n行,每行两个整数,表示 ki,bi。
    接下来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

    n,m≤200000,k,b,x<1000000007。

    一看这个题的样子就是线段树,我们观察一次函数性质则有

    剩下的线段树的区间合并一下它的左右儿子就好了

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 const ll mod = 1e9+7;
     6 const int maxn = 210000;
     7 int kk[maxn],bb[maxn];
     8 int n,m;
     9 char op[5];
    10 struct node
    11 {
    12     int l,r;
    13     ll k,b;
    14 }tree[maxn<<2];
    15 node Union (node x,node y)
    16 {
    17     node tmp;
    18     tmp.l=x.l,tmp.r=y.r;
    19     tmp.k=(x.k*y.k)%mod;
    20     tmp.b=((y.k*x.b)%mod+y.b)%mod;
    21     return tmp;
    22 }
    23 void pushup(int now)
    24 {
    25     tree[now] = Union(tree[now<<1],tree[now<<1|1]);
    26 }
    27 void build (int now,int L,int R)
    28 {
    29     if (L==R){
    30         tree[now].l=L,tree[now].r=L;
    31         tree[now].k=kk[L];tree[now].b=bb[L];
    32         return ;
    33     }
    34     int mid = (L+R)>>1;
    35     build(now<<1,L,mid);
    36     build(now<<1|1,mid+1,R);
    37     pushup(now);
    38 }
    39 void update (int now,int pos,int kkk,int bbb)
    40 {
    41     if (tree[now].l==tree[now].r){
    42         tree[now].k=kkk,tree[now].b=bbb;
    43         return;
    44     }
    45     int mid = (tree[now].l+tree[now].r)/2;
    46     if (pos<=mid)
    47         update(now<<1,pos,kkk,bbb);
    48     else
    49         update(now<<1|1,pos,kkk,bbb);
    50     pushup(now);
    51 }
    52 node query (int now,int L,int R)
    53 {
    54     if (tree[now].l==L&&tree[now].r==R)
    55         return tree[now];
    56     int mid = (tree[now].l+tree[now].r)/2;
    57     if (R<=mid)
    58         return query(now<<1,L,R);
    59     else if (L>mid)
    60         return query(now<<1|1,L,R);
    61     else
    62         return Union(query(now<<1,L,mid),query(now<<1|1,mid+1,R));
    63 }
    64 int main()
    65 {
    66     //freopen("de.txt","r",stdin);
    67     scanf("%d%d",&n,&m);
    68     for (int i=1;i<=n;++i)
    69         scanf("%d%d",&kk[i],&bb[i]);
    70     build(1,1,n);
    71     for (int i=0;i<m;++i){
    72         scanf("%s",op);
    73         if (op[0]=='M'){
    74             int x,y,z;
    75             scanf("%d%d%d",&x,&y,&z);
    76             update(1,x,y,z);
    77         }
    78         else{
    79             int lll,rrr,xx;
    80             scanf("%d%d%d",&lll,&rrr,&xx);
    81             node anss=query(1,lll,rrr);
    82             ll ans = ((anss.k*xx)%mod+anss.b)%mod;
    83             printf("%lld
    ",ans);
    84         }
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    WEP编码格式
    OSK VFS read数据流分析
    科学剖析濒死体验 "复生"者讲述"死"前1秒钟
    Android的开发相对于tizen的开发难度
    minix文件系统分析
    贴给小程序(1) 查找第一个0值
    Linux下的QQ
    OSK USB 驱动
    LRU算法之hash+list实现(转)
    插入排序
  • 原文地址:https://www.cnblogs.com/agenthtb/p/7616365.html
Copyright © 2011-2022 走看看