zoukankan      html  css  js  c++  java
  • P2023 [AHOI2009]维护序列

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

    输入输出格式

    输入格式:

    第一行两个整数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)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

    输出格式:

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

    输入输出样例

    输入样例#1:
    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
    输出样例#1:
    2
    35
    8
    

    说明

    【样例说明】

    初始时数列为(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

    Source: Ahoi 2009

    调了一个半小时,调不出来

    不调了、、

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define lli long long 
      7 using namespace std;
      8 const int MAXN=500001;
      9 lli n,m,mod,ans;
     10 void read(lli & n)
     11 {
     12     char c='+';lli x=0;bool flag=0;
     13     while(c<'0'||c>'9')
     14     {c=getchar();if(c=='-')flag=1;}
     15     while(c>='0'&&c<='9')
     16     {x=x*10+(c-48),c=getchar();}
     17     flag==1?n=-x:n=x;
     18 }
     19 struct node
     20 {
     21     lli l,r,w,k,fc,fj;
     22 }tree[MAXN*4];
     23 void pushdown(lli k,lli ll,lli rr,lli mid)
     24 {
     25     tree[k<<1].w*=tree[k].fc%mod;
     26     tree[k<<1|1].w*=tree[k].fc%mod;
     27     tree[k<<1].w=(tree[k<<1].w+tree[k].fj*(mid-ll+1))%mod;
     28     tree[k<<1|1].w=(tree[k<<1|1].w+tree[k].fj*(rr-mid))%mod;
     29     
     30     tree[k<<1].fc%=mod;tree[k<<1|1].fc%=mod;
     31     tree[k<<1].fj%=mod;tree[k<<1|1].fj%=mod;
     32     tree[k<<1].w%=mod;tree[k<<1|1].w%=mod;
     33     
     34     tree[k<<1].fc*=tree[k].fc%mod;tree[k<<1|1].fc*=tree[k].fc%mod;
     35     tree[k<<1].fj*=tree[k].fc%mod;tree[k<<1|1].fj*=tree[k].fc%mod;
     36     tree[k<<1].fj=(tree[k<<1].fj+tree[k].fj)%mod;
     37     tree[k<<1|1].fj=(tree[k<<1|1].fj+tree[k].fj)%mod;
     38     
     39     
     40     tree[k].fc=1;
     41     tree[k].fj=0;
     42     
     43     
     44     tree[k<<1].fc%=mod;tree[k<<1|1].fc%=mod;
     45     tree[k<<1].fj%=mod;tree[k<<1|1].fj%=mod;
     46     tree[k<<1].w%=mod;tree[k<<1|1].w%=mod;
     47 }
     48 void update(lli k)
     49 {
     50     tree[k].w=(tree[k<<1].w+tree[k<<1|1].w)%mod;
     51 }
     52 void build_tree(lli ll,lli rr,lli k)
     53 {
     54     tree[k].l=ll;tree[k].r=rr;tree[k].k=k;
     55     tree[k].fc=1;tree[k].fj=0;
     56     if(tree[k].l==tree[k].r)
     57     {
     58         read(tree[k].w);
     59         tree[k].w%=mod;
     60         return ;
     61     }
     62     lli mid=(ll+rr)>>1;
     63     build_tree(ll,mid,k<<1);
     64     build_tree(mid+1,rr,k<<1|1);
     65     update(k);
     66 }
     67 void interval_mul(lli k,lli ll,lli rr,lli v)
     68 {
     69     if(ll>tree[k].r||rr<tree[k].l)
     70     return ;
     71     if(tree[k].l>=ll&&tree[k].r<=rr)
     72     {
     73         tree[k].w*=v%mod;
     74         tree[k].fc*=v%mod;
     75         tree[k].fj*=v%mod;
     76         return ;
     77     }
     78     lli mid=(tree[k].l+tree[k].r)>>1;
     79     pushdown(k,tree[k].l,tree[k].r,mid);
     80     if(ll<=mid)
     81         interval_mul(k<<1,ll,rr,v);
     82     if(rr>mid)
     83         interval_mul(k<<1|1,ll,rr,v);
     84     update(k);
     85 }
     86 void interval_add(lli k,lli ll,lli rr,lli v)
     87 {
     88     if(ll>tree[k].r||rr<tree[k].l)
     89     return ;
     90     if(tree[k].l>=ll&&tree[k].r<=rr)
     91     {
     92         tree[k].w=(tree[k].w+v*(tree[k].r-tree[k].l+1))%mod;
     93         //tree[k].fc*=v%mod;
     94         tree[k].fj=(tree[k].fj+v)%mod;
     95         return ;
     96     }
     97     lli mid=(tree[k].l+tree[k].r)>>1;
     98     pushdown(k,tree[k].l,tree[k].r,mid);
     99     if(ll<=mid)
    100         interval_add(k<<1,ll,rr,v);
    101     if(rr>mid)
    102         interval_add(k<<1|1,ll,rr,v);
    103     update(k);
    104 
    105 }
    106 void interval_ask(lli k,lli ll,lli rr)
    107 {
    108     if(ll>tree[k].r||rr<tree[k].l)
    109     return ;
    110     if(tree[k].l>=ll&&tree[k].r<=rr)
    111     {
    112         ans=(ans+tree[k].w)%mod;
    113         return ;
    114     }
    115     lli mid=(tree[k].l+tree[k].r)>>1;
    116     pushdown(k,tree[k].l,tree[k].r,mid);
    117     if(ll<=mid)
    118         interval_ask(k<<1,ll,rr);
    119     if(rr>mid)
    120         interval_ask(k<<1|1,ll,rr);
    121     update(k);
    122 }
    123 int main()
    124 {
    125     read(n);read(mod);
    126     build_tree(1,n,1);
    127     read(m);
    128     for(lli i=1;i<=m;i++)
    129     {
    130         lli how,x,y,c;
    131         read(how);
    132         if(how==1)
    133         {
    134             read(x);read(y);read(c);
    135             interval_mul(1,x,y,c%mod);//
    136         }
    137         else if(how==2)
    138         {
    139             read(x);read(y);read(c);
    140             interval_add(1,x,y,c%mod);//
    141         }
    142         else if(how==3)
    143         {
    144             ans=0;
    145             read(x);read(y);
    146             interval_ask(1,x,y);
    147             printf("%lld
    ",ans);
    148         }
    149     }
    150     return 0;
    151 }
    60分
     1 #include<iostream>
     2 #include<cstdio>
     3 #define lli long long int 
     4 #define re register
     5 #define LL long long
     6 #define M 500000
     7 using namespace std;
     8 void read(lli & n)
     9 {
    10     char c='+';lli x=0;bool flag=0;
    11     while(c<'0'||c>'9')
    12     {c=getchar();if(c=='-')flag=1;}
    13     while(c>='0'&&c<='9')
    14     {x=x*10+(c-48),c=getchar();}
    15     flag==1?n=-x:n=x;
    16 }
    17 LL mogician,a[M/2+1];
    18 int n;
    19 struct Tree{
    20     LL sum,add,mult;
    21 }tr[M+1];
    22 inline void build(int k,int l,int r){
    23     tr[k].mult=1;
    24     if(l==r){
    25         tr[k].sum=a[l];
    26         return ;
    27     }
    28     int mid=(l+r)>>1;
    29     build(k<<1,l,mid);
    30     build(k<<1|1,mid+1,r);
    31     tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%mogician;
    32 }
    33 inline void Work_Out(int k,int l,int r,LL mu,LL ad){
    34     tr[k].add=(tr[k].add*mu+ad)%mogician;
    35     tr[k].mult=(tr[k].mult*mu)%mogician;
    36     tr[k].sum=(tr[k].sum*mu+(r-l+1)*ad)%mogician;
    37 }
    38 inline void Push_Down(int k,int l,int r){
    39     if(tr[k].add==0&&tr[k].mult==1)
    40         return ;
    41     int mid=(l+r)>>1;
    42     Work_Out(k<<1,l,mid,tr[k].mult,tr[k].add);
    43     Work_Out(k<<1|1,mid+1,r,tr[k].mult,tr[k].add);
    44     tr[k].add=0;
    45     tr[k].mult=1;
    46 }
    47 inline void Lazy_Tag(int k,int l,int r,int x,int y,LL mu,LL ad){
    48     if(x<=l&&r<=y){
    49         Work_Out(k,l,r,mu,ad);
    50         return ;
    51     }
    52     Push_Down(k,l,r);
    53     int mid=(l+r)>>1;
    54     if(x<=mid)
    55         Lazy_Tag(k<<1,l,mid,x,y,mu,ad);
    56     if(mid<y)
    57         Lazy_Tag(k<<1|1,mid+1,r,x,y,mu,ad);
    58     tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%mogician;
    59 }
    60 inline LL Q(int k,int l,int r,int x,int y){
    61     if(x<=l&&r<=y)
    62         return tr[k].sum%mogician;
    63     Push_Down(k,l,r);
    64     int mid=(l+r)>>1;
    65     return    ((x<=mid?Q(k<<1,l,mid,x,y)%mogician:0)+(mid<y?Q(k<<1|1,mid+1,r,x,y)%mogician:0))%mogician;
    66 }
    67 int m,d,x,y;
    68 LL k;
    69 int main(){
    70     
    71     scanf("%lld%lld",&n,&mogician);
    72     for(re int i=1;i<=n;i++){
    73         scanf("%lld",&a[i]);
    74         a[i]%=mogician;
    75     }
    76     build(1,1,n);
    77     scanf("%d",&m);
    78     for(re int i=1;i<=m;i++){
    79         scanf("%d%d%d",&d,&x,&y);
    80         if(d==3)
    81             printf("%lld
    ",Q(1,1,n,x,y));
    82         else{
    83             scanf("%lld",&k);
    84             k%=mogician;
    85             d==1?Lazy_Tag(1,1,n,x,y,k,0):Lazy_Tag(1,1,n,x,y,1,k);
    86         }
    87     }
    88     return 0;
    89 }
    AC
  • 相关阅读:
    easyui 如何为datagrid添加自定义列属性(如:width,align,editor)
    Oracle中如何修改已存在数据的列名的数据类型
    web 表单方式上传文件方法(不用flash插件)
    easyui datagrid怎么动态获取表头的列名及显示名称
    如何解决“HttpException (0x80004005): 超过了最大请求长度”问题
    oracle中“ORA-00060: 等待资源时检测到死锁” 或存储过程编译卡死 解决方法
    Chosen v1.8.7 动态添加下拉选项
    【转发】vue v-for循环的用法(索引,键值)
    Vue Select默认选择项设置方法
    Vue内部使用setInterval轮询数据,对象数据重新赋值后再次渲染数据
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/7082254.html
Copyright © 2011-2022 走看看