zoukankan      html  css  js  c++  java
  • bzoj1798[Ahoi2009]Seq 维护序列seq

    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 program rrr(input,output);
     2 type
     3   treetype=record
     4      l,r:longint;
     5      mul,plus,sum:int64;
     6   end;
     7 var
     8   a:array[0..400040]of treetype;
     9   num:array[0..100010]of int64;
    10   n,m,i,opt,x,y:longint;
    11   c,p:int64;
    12 procedure build(k,l,r:longint);
    13 var
    14   mid,i:longint;
    15 begin
    16    a[k].l:=l;a[k].r:=r;a[k].mul:=1;a[k].plus:=0;
    17    if l=r then begin a[k].sum:=num[l];exit; end;
    18    mid:=(l+r)>>1;i:=k<<1;
    19    build(i,l,mid);
    20    build(i+1,mid+1,r);
    21    a[k].sum:=(a[i].sum+a[i+1].sum) mod p;
    22 end;
    23 procedure pushdown(k:longint);
    24 var
    25   i:longint;
    26 begin
    27    if (a[k].plus=0) and (a[k].mul=1) then exit;
    28    if a[k].l=a[k].r then begin a[k].plus:=0;a[k].mul:=1;exit; end;
    29    i:=k<<1;
    30    a[i].sum:=(a[i].sum*a[k].mul+a[k].plus*(a[i].r-a[i].l+1)) mod p;
    31    a[i+1].sum:=(a[i+1].sum*a[k].mul+a[k].plus*(a[i+1].r-a[i+1].l+1)) mod p;
    32    a[i].mul:=a[i].mul*a[k].mul mod p;a[i].plus:=(a[i].plus*a[k].mul+a[k].plus) mod p;
    33    a[i+1].mul:=a[i+1].mul*a[k].mul mod p;a[i+1].plus:=(a[i+1].plus*a[k].mul+a[k].plus) mod p;
    34    a[k].mul:=1;a[k].plus:=0;
    35 end;
    36 procedure changemul(k:longint);
    37 var
    38   mid,i:longint;
    39 begin
    40    pushdown(k);
    41    if (x<=a[k].l) and (a[k].r<=y) then begin a[k].sum:=a[k].sum*c mod p;a[k].mul:=c mod p;exit; end;
    42    mid:=(a[k].l+a[k].r)>>1;i:=k<<1;
    43    if x<=mid then changemul(i);
    44    if mid<y then changemul(i+1);
    45    a[k].sum:=(a[i].sum+a[i+1].sum) mod p;
    46 end;
    47 procedure changeplus(k:longint);
    48 var
    49   mid,i:longint;
    50 begin
    51    pushdown(k);
    52    if (x<=a[k].l) and (a[k].r<=y) then begin a[k].sum:=(a[k].sum+c*(a[k].r-a[k].l+1)) mod p;a[k].plus:=c mod p;exit; end;
    53    mid:=(a[k].l+a[k].r)>>1;i:=k<<1;
    54    if x<=mid then changeplus(i);
    55    if mid<y then changeplus(i+1);
    56    a[k].sum:=(a[i].sum+a[i+1].sum) mod p;
    57 end;
    58 function ask(k:longint):int64;
    59 var
    60   mid,i:longint;
    61 begin
    62    pushdown(k);
    63    if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].sum);
    64    mid:=(a[k].l+a[k].r)>>1;i:=k<<1;
    65    ask:=0;
    66    if x<=mid then ask:=ask(i) mod p;
    67    if mid<y then ask:=(ask+ask(i+1)) mod p;
    68 end;
    69 begin
    70    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
    71    readln(n,p);
    72    for i:=1 to n do read(num[i]);
    73    build(1,1,n);
    74    readln(m);
    75    for i:=1 to m do
    76       begin
    77          read(opt,x,y);
    78          if opt=1 then begin readln(c);changemul(1); end
    79          else if opt=2 then begin readln(c);changeplus(1); end
    80          else writeln(ask(1));
    81       end;
    82    close(input);close(output);
    83 end.
  • 相关阅读:
    DNS欺骗&嗅探监听
    linux下的ARP攻击(kali)
    隐匿攻击
    跨边界传输之反弹shell
    跨边界传输之内网代理
    跨边界传输之端口转发
    权限维持
    内网提权-服务篇
    内网提权-系统篇
    Laxcus大数据管理系统2.0(14)- 后记
  • 原文地址:https://www.cnblogs.com/Currier/p/6411535.html
Copyright © 2011-2022 走看看