• 值得一做》关于双标记线段树两三事BZOJ 1798 (NORMAL-)


      这是一道双标记线段树的题,很让人很好的预习/学习/复习线段树,我不知道它能让别人学习什么,反正让我对线段树的了解更加深刻。

      题目没什么好讲的,程序也没什么好讲的,所以也没有什么题解,但是值得一做

      给出题目&代码

    Description

    老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

    Input

    第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

    Output

    对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

    Sample Input

    7 43
    1 2 3 4 5 6 7
    5
    1 2 5 5
    3 2 4
    2 3 7 9
    3 1 3
    3 4 7

    Sample Output

    2
    35
    8

    HINT

    【样例说明】

    初始时数列为(1,2,3,4,5,6,7)。
    经过第1次操作后,数列为(1,10,15,20,25,6,7)。
    对第2次操作,和为10+15+20=45,模43的结果是2。
    经过第3次操作后,数列为(1,10,24,29,34,15,16}
    对第4次操作,和为1+10+24=35,模43的结果是35。
    对第5次操作,和为29+34+15+16=94,模43的结果是8。

    测试数据规模如下表所示

    数据编号 1 2 3 4 5 6 7 8 9 10
    N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
    M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

      1 /**************************************************************
      2     Problem: 1798
      3     User: PencilWang
      4     Language: C++
      5     Result: Accepted
      6     Time:4320 ms
      7     Memory:27388 kb
      8 ****************************************************************/
      9  
     10 #include<stdio.h>
     11 long long n,m;
     12 long long MOD;
     13 struct shit{
     14 int L,R;
     15 long long num,j,c;
     16 }s[800100];
     17 long long w[200100];
     18 long long C,J;
     19 void fuck(int p)
     20 {
     21     s[p].num=(s[p<<1].num+s[p<<1|1].num)%MOD;
     22     return ;
     23 }
     24 void suck(int p)
     25 {
     26     int mid=(s[p].L+s[p].R)>>1;
     27     int LL=p<<1,RR=p<<1|1;
     28     s[LL].num=(s[LL].num*s[p].c+(s[LL].R-s[LL].L+1)*s[p].j)%MOD;
     29     s[LL].c=(s[LL].c*s[p].c)%MOD;
     30     s[LL].j=(s[LL].j*s[p].c+s[p].j)%MOD;
     31     s[RR].num=(s[RR].num*s[p].c+(s[RR].R-s[RR].L+1)*s[p].j)%MOD;
     32     s[RR].c=(s[RR].c*s[p].c)%MOD;
     33     s[RR].j=(s[RR].j*s[p].c+s[p].j)%MOD;
     34     s[p].c=1,s[p].j=0;
     35     return ;
     36 }
     37 void build(int p,int l,int r)
     38 {
     39     s[p].L=l;
     40     s[p].R=r;
     41     s[p].c=1;
     42     s[p].j=0;
     43     if(l==r)
     44     {
     45     s[p].num=w[l];
     46     return ;
     47     }
     48     int mid=(l+r)>>1;
     49     build(p<<1,l,mid);
     50     build(p<<1|1,mid+1,r);
     51     fuck(p);
     52     return ;
     53 }
     54 void cc(int a,int b,int x,int p)
     55 {
     56     if(a<=s[p].L&&s[p].R<=b)
     57     {
     58     s[p].num=(x*s[p].num)%MOD;
     59     s[p].c=(x*s[p].c)%MOD;
     60     s[p].j=(x*s[p].j)%MOD;
     61     return ;
     62     }
     63     suck(p);
     64     int mid=(s[p].L+s[p].R)>>1;
     65     if(mid>=a)cc(a,b,x,p<<1);
     66     if(mid<b)cc(a,b,x,p<<1|1);
     67     fuck(p);
     68     return ;
     69 }
     70 void jj(int a,int b,int x,int p)
     71 {
     72     if(a<=s[p].L&&s[p].R<=b)
     73     {
     74     s[p].num=(s[p].num+x*(s[p].R-s[p].L+1))%MOD;
     75     s[p].j=(x+s[p].j)%MOD;
     76     return ;
     77     }
     78     suck(p);
     79     int mid=(s[p].L+s[p].R)>>1;
     80     if(mid>=a)jj(a,b,x,p<<1);
     81     if(mid<b)jj(a,b,x,p<<1|1);
     82     fuck(p);
     83     return ;
     84 }
     85 long long Q(int p,int a,int b)
     86 {
     87     if(a<=s[p].L&&s[p].R<=b)
     88     return s[p].num%MOD;
     89     int mid=(s[p].L+s[p].R)>>1;
     90     suck(p);
     91     long long ANS=0;
     92     if(a<=mid)
     93     {
     94     ANS+=Q(p<<1,a,b);
     95     ANS%=MOD;
     96     }
     97     if(b>mid)
     98     {
     99     ANS+=Q(p<<1|1,a,b);
    100     ANS%=MOD;
    101     }
    102     fuck(p);
    103     return ANS;
    104 }
    105 int main()
    106 {
    107     long long a,b,c,f;
    108     scanf("%lld%lld",&n,&MOD);
    109     for(int i=1;i<=n;i++)scanf("%lld",w+i);
    110     build(1,1,n);
    111     scanf("%lld",&m);
    112     while(m--)
    113     {
    114         scanf("%lld%lld%lld",&f,&a,&b);
    115         if(f==1)
    116         {
    117         scanf("%lld",&c);
    118         c%=MOD;
    119         cc(a,b,c,1);
    120         }
    121         else if(f==2)
    122         {
    123         scanf("%lld",&c);
    124         c%=MOD;
    125         jj(a,b,c,1);
    126         }
    127         else
    128         printf("%lld
    ",Q(1,a,b)%MOD);
    129     }
    130     return 0;
    131 }
    1798
  • 相关阅读:
    Kprobes—insight into the Linux kernel—replace kernel function with module
    Go将统治下一个十年
    linux—网络仿真开源软件—network simulator—ns
    Serval Project——Android
    CentOS7—Firefox—截图工具—fireshot插件
    Wi-Fi Direct技术
    国产CPU迷局 龙芯该如何参与市场竞争
    《深入理解Android:Wi-Fi,NFC和GPS》—android源码下载
    wifi direct—深入理解Wi-Fi P2P
    c语言学习基础:[1]开发工具介绍
  • 原文地址:https://www.cnblogs.com/PencilWang/p/5958786.html
Copyright © 2020-2023  润新知