zoukankan      html  css  js  c++  java
  • 线段树2

      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 typedef long long ll;
      5 const int N=1e6+5;
      6 struct tree
      7 {
      8     int l,r;
      9     ll sum,lz1,lz2;
     10 }t[N];
     11 ll n,m,P;
     12 ll a[N];
     13 void push_up(int p)
     14 {
     15     t[p].sum=(t[p<<1].sum+t[p<<1|1].sum)%P;
     16 }
     17 void push_down(int p)
     18 {
     19     if(t[p].l==t[p].r) return;
     20     ll q;
     21     if(t[p].lz1!=1)
     22     {
     23     q=t[p].lz1;
     24     t[p].lz1=1;
     25     t[p<<1].lz1=t[p<<1].lz1*q%P;
     26     t[p<<1].lz2=t[p<<1].lz2*q%P;
     27     t[p<<1|1].lz1=t[p<<1|1].lz1*q%P;
     28     t[p<<1|1].lz2=t[p<<1|1].lz2*q%P;
     29     t[p<<1].sum=t[p<<1].sum*q%P;
     30     t[p<<1|1].sum=t[p<<1|1].sum*q%P;
     31     }
     32     if(t[p].lz2)
     33     {
     34     q=t[p].lz2;
     35     t[p].lz2=0;
     36     t[p<<1].lz2=(t[p<<1].lz2+q)%P;
     37     t[p<<1|1].lz2=(t[p<<1|1].lz2+q)%P;
     38     t[p<<1].sum=(t[p<<1].sum+(t[p<<1].r-t[p<<1].l+1)*q)%P;
     39     t[p<<1|1].sum=(t[p<<1|1].sum+(t[p<<1|1].r-t[p<<1|1].l+1)*q)%P;
     40     }
     41 }
     42 
     43 void build(int p,int l,int r)
     44 {
     45     t[p].l=l;t[p].r=r;t[p].sum=t[p].lz2=0;t[p].lz1=1;
     46     if(l==r) return (void)(t[p].sum=a[l]);
     47     int mid=l+r>>1;
     48     build(p<<1,l,mid);
     49     build(p<<1|1,mid+1,r);
     50     push_up(p);
     51 }
     52 void modify1(int p,int l,int r,ll w)
     53 {
     54     if(l==t[p].l && r==t[p].r)
     55     {
     56     t[p].lz1=t[p].lz1*w%P;
     57     t[p].lz2=t[p].lz2*w%P;
     58     t[p].sum=t[p].sum*w%P;
     59     return;
     60     }
     61     push_down(p);
     62     int mid=t[p].l+t[p].r>>1;
     63     if(mid>=r) modify1(p<<1,l,r,w);
     64     else if(l>mid) modify1(p<<1|1,l,r,w);
     65     else modify1(p<<1,l,mid,w),modify1(p<<1|1,mid+1,r,w);
     66     push_up(p);
     67 }
     68 void modify2(int p,int l,int r,ll w)
     69 {
     70     if(l==t[p].l && r==t[p].r)
     71     {
     72     t[p].lz2=(t[p].lz2+w)%P;
     73     t[p].sum=(t[p].sum+(t[p].r-t[p].l+1)*w)%P;
     74     return;
     75     }
     76     push_down(p);
     77     int mid=t[p].l+t[p].r>>1;
     78     if(mid>=r) modify2(p<<1,l,r,w);
     79     else if(l>mid) modify2(p<<1|1,l,r,w);
     80     else modify2(p<<1,l,mid,w),modify2(p<<1|1,mid+1,r,w);
     81     push_up(p);
     82 }
     83 ll query(int p,int l,int r)
     84 {
     85     //  printf("%d %d %d %d %lld
    ",l,r,t[p].l,t[p].r,t[p].sum);
     86     if(l==t[p].l && r==t[p].r) return t[p].sum;
     87     push_down(p);
     88     int mid=t[p].l+t[p].r>>1;
     89 
     90     if(mid>=r) return query(p<<1,l,r);
     91     if(l>mid) return query(p<<1|1,l,r);
     92     return (query(p<<1,l,mid)+query(p<<1|1,mid+1,r))%P;
     93 }
     94 int main()
     95 {
     96     scanf("%lld%lld%lld",&n,&m,&P);
     97     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
     98     build(1,1,n);
     99     ll k;
    100     for(int i=1,op,x,y;i<=m;i++)
    101     {
    102 //    for(int i=1;i<=n;i++) printf("%d:%lld
    ",i,query(1,i,i));
    103     scanf("%d",&op);
    104     if(op==1)scanf("%d%d%lld",&x,&y,&k),modify1(1,x,y,k);
    105     if(op==2)scanf("%d%d%lld",&x,&y,&k),modify2(1,x,y,k);
    106     if(op==3)scanf("%d%d",&x,&y),printf("%lld
    ",query(1,x,y));
    107       
    108     }
    109     return 0;
    110 }

    题目描述

    如题,已知一个数列,你需要进行下面三种操作:

    1.将某区间每一个数乘上x

    2.将某区间每一个数加上x

    3.求出某区间每一个数的和

    输入输出格式

    输入格式:

    第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

    操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

    操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果

    输出格式:

    输出包含若干行整数,即为所有操作3的结果。

    输入输出样例

    输入样例#1: 复制
    5 5 38
    1 5 4 2 3
    2 1 4 1
    3 2 5
    1 2 4 2
    2 3 5 5
    3 1 4
    输出样例#1: 复制
    17
    2

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^)

    样例说明:

    故输出应为17、2(40 mod 38=2)

  • 相关阅读:
    Bzoj4873 [SXOI2017]寿司餐厅
    Bzoj4870 [SXOI2017]组合数问题
    Bzoj4820 [Sdoi2017]硬币游戏
    Bzoj4816 [Sdoi2017]数字表格
    HDU2089 不要62
    Python——lambda函数
    Django——在线教育项目总结
    Django项目——CRM
    数据库——MongoDB的安装
    母猪的产后护理——一些零碎的知识
  • 原文地址:https://www.cnblogs.com/rax-/p/9026113.html
Copyright © 2011-2022 走看看