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

    题解:

    看到这种题目,一看就是线段树

    很明显的区间线段树

    加法反正不用说

    乘法的时候往加法的地方也要翻倍

    代码:

    #include<bits/stdc++.h> 
    using namespace std;
    typedef long long ll;
    const int N=400005;
    ll p,v,sum_,addv[N],mulv[N],sumv[N],a[N];
    int n,m,c,x,y;
    void pushdown(int o,int l,int l1,int r,int r1)
    {
        sumv[o*2]=(sumv[o*2]*mulv[o]+addv[o]*(l1-l+1))%p;
        sumv[o*2+1]=(sumv[o*2+1]*mulv[o]+addv[o]*(r1-r+1))%p;
        addv[o*2]=(addv[o*2]*mulv[o]+addv[o])%p;
        addv[o*2+1]=(addv[o*2+1]*mulv[o]+addv[o])%p;
        mulv[o*2]=(mulv[o*2]*mulv[o])%p;
        mulv[o*2+1]=(mulv[o*2+1]*mulv[o])%p;
        mulv[o]=1;
        addv[o]=0;
    }
    void updatemul(int o,int l,int r)
    {    
        if(x<=l&&r<=y)
         {
            mulv[o]=(mulv[o]*v)%p;
            addv[o]=(addv[o]*v)%p;
            sumv[o]=(sumv[o]*v)%p;
            return ;
         }
        int mid=(l+r)>>1;
        pushdown(o,l,mid,mid+1,r);
        if(x<=mid)updatemul(o*2,l,mid);
        if(y>mid)updatemul(o*2+1,mid+1,r);
        sumv[o]=(sumv[o*2]+sumv[o*2+1])%p;
    }
    void updateadd(int o,int l,int r)
    {
        if(x<=l&&r<=y)
         {
            addv[o]=(addv[o]+v)%p;
            sumv[o]=(sumv[o]+v*(r-l+1))%p;
            return ;
         }
        int mid=(l+r)>>1;
        pushdown(o,l,mid,mid+1,r);
        if(x<=mid)updateadd(o*2,l,mid);
        if(y>mid)updateadd(o*2+1,mid+1,r);
        sumv[o]=(sumv[o*2]+sumv[o*2+1])%p;
    }
    void create(int o,int l,int r)
    {
        addv[o]=0;
        mulv[o]=1;
        if(l==r)
         {
            sumv[o]=a[l];
            return ;
         }
        int mid=(l+r)>>1;
        create(o*2,l,mid);
        create(o*2+1,mid+1,r);
        sumv[o]=(sumv[o*2]+sumv[o*2+1])%p;
    }
    void query(int o,int l,int r)
    {
        if(x<=l&&r<=y)
         {
            sum_+=sumv[o]%p;
            sum_%=p;
            return ;
         }
        int mid=(l+r)>>1;
        pushdown(o,l,mid,mid+1,r);
        if(x<=mid)query(o*2,l,mid);
        if(y>mid)query(o*2+1,mid+1,r);
        sumv[o]=(sumv[o*2]+sumv[o*2+1])%p;
    }
    int main()
    {
        scanf("%d%d",&n,&p);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        create(1,1,n);
        scanf("%d",&m);
        while (m--)
         {
            scanf("%d%d%d",&c,&x,&y);
            if(c==1)
             {
                scanf("%d",&v);
                updatemul(1,1,n);
             }
            if(c==2)
             {
                scanf("%d",&v);
                updateadd(1,1,n);
             }
            if(c==3)
             {
                sum_=0;
                query(1,1,n);
                printf("%lld
    ",sum_);
             }
         }
        return 0;
    }
  • 相关阅读:
    文档的几何形状和滚动
    聊聊并发——生产者消费者模式
    在JavaScript中什么时候使用==是正确的?
    HTML5使用canvas画图时,图片被自动放大模糊的问题
    获取元素的几种方式
    利用jQuery和CSS实现环形进度条
    最实用、最常用的jQuery代码片段
    表格样式
    javascript常量的定义
    null 和 undefined 的区别
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7705624.html
Copyright © 2011-2022 走看看