zoukankan      html  css  js  c++  java
  • 【JSOI 2014】序列维护

    【题目链接】

               点击打开链接

    【算法】

             线段树

             注意标记下传

    【代码】

              

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 500000
    
    typedef long long LL;
    
    struct SegTreeNode {
        LL l,r,sum,lazya,lazyb;    
    }tree[MAXN+10];
    
    LL i,N,P,Q,l,r,x,opt;
    LL a[MAXN+10];
    
    template <typename T> void read(T &x) {
        LL f=1; char c = getchar(); x=0;
        for (; !isdigit(c); c = getchar()) { if (c=='-') f=-1; }
        for (; isdigit(c); c = getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    inline void write(LL x) {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x / 10 > 0) write(x/10);
        putchar(x%10+'0');    
    } 
    
    inline void pushup(LL index) {
        tree[index].sum = (tree[index*2].sum + tree[index*2+1].sum) % P;    
    }
    
    inline void pushdown(LL index) { 
        tree[index*2].sum = (tree[index*2].sum * tree[index].lazya + tree[index].lazyb * (tree[index*2].r - tree[index*2].l + 1)) % P;
        tree[index*2+1].sum = (tree[index*2+1].sum * tree[index].lazya + tree[index].lazyb * (tree[index*2+1].r - tree[index*2+1].l + 1)) % P;
        tree[index*2].lazya = (tree[index*2].lazya * tree[index].lazya) % P;
        tree[index*2+1].lazya = (tree[index*2+1].lazya * tree[index].lazya) % P;
        tree[index*2].lazyb = (tree[index*2].lazyb * tree[index].lazya + tree[index].lazyb) % P;
        tree[index*2+1].lazyb = (tree[index*2+1].lazyb * tree[index].lazya + tree[index].lazyb) % P;
        tree[index].lazya = 1; tree[index].lazyb = 0;
    }
    
    inline void build(LL index,LL l,LL r) {
        LL mid;
        tree[index].l = l;
        tree[index].r = r;
        tree[index].lazya = 1; 
        if (l == r) tree[index].sum = a[l] % P;
        else {
            mid = (l + r) >> 1;
            build(index*2,l,mid);
            build(index*2+1,mid+1,r);
            pushup(index);
        }    
    }
    
    inline void changea(int index,int l,int r,int x) {
        LL mid;
        pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) {
            tree[index].sum = tree[index].sum * x % P; 
            tree[index].lazya = (tree[index].lazya * x) % P;  
            tree[index].lazyb = (tree[index].lazyb * x) % P;
        }else {
                if (tree[index].l == tree[index].r) return;
            mid = (tree[index].l + tree[index].r) >> 1;
               if (r <= mid) changea(index*2,l,r,x);
            else if (l >= mid + 1) changea(index*2+1,l,r,x);
            else {
                changea(index*2,l,mid,x);
                changea(index*2+1,mid+1,r,x);
            }
            pushup(index);
        } 
    }
    
    inline void changeb(LL index,LL l,LL r,LL x) {
        LL mid;
        pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) {
            tree[index].sum = (tree[index].sum + x * (tree[index].r - tree[index].l + 1)) % P;
            tree[index].lazyb = (tree[index].lazyb + x) % P;  
        }else {
                if (tree[index].l == tree[index].r) return;
            mid = (tree[index].l + tree[index].r) >> 1;
            if (r <= mid) changeb(index*2,l,r,x);
            else if (l >= mid + 1) changeb(index*2+1,l,r,x);
            else {
                if (tree[index].l == tree[index].r) return;
                changeb(index*2,l,mid,x);
                changeb(index*2+1,mid+1,r,x);
            }
            pushup(index);
        } 
    }
    
    inline LL query(LL index,LL l,LL r) {
        LL mid;
        pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) return tree[index].sum;  
        else {
                if (tree[index].l == tree[index].r) return 0;
            mid = (tree[index].l + tree[index].r) >> 1;
            if (r <= mid) return query(index*2,l,r);
            else if (l >= mid + 1) return query(index*2+1,l,r);
            else return (query(index*2,l,mid) + query(index*2+1,mid+1,r)) % P;
        }
    }
    
    int main() {
        
        read(N); read(P);
        
        for (i = 1; i <= N; i++) read(a[i]);
        
        build(1,1,N);
        
        read(Q);
        
        while (Q--) {
            read(opt);
            if (opt == 1) {
                read(l); read(r); read(x);
                changea(1,l,r,x);
            }else if (opt == 2) {
                read(l); read(r); read(x);
                changeb(1,l,r,x);
            }else {
                read(l); read(r);
                write(query(1,l,r));
                puts("");    
            }
        }    
        
        return 0;
        
    } 
  • 相关阅读:
    PHP 如何阻止用户上传成人照片或者裸照
    centos 从php5.1升级php到5.3的方法
    用jQuery实现鼠标移动切换图片动画
    利用表格实现大图轮播
    css导行下拉动画
    java script 基本函数
    java script 数组去重两种方法
    java script两个列表之间移动数据
    JavaScript做个时间表 Date()
    JS For 循环详解;棋盘放粮食 64;冒泡排序实例
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196412.html
Copyright © 2011-2022 走看看