• 题解 T45322 【yizimi的前缀积】


    yizimi的前缀积

    前缀积?

    想的美!!!

    此题卡分块(别想混过去),st表,平衡树,,,

    时限在那里呐 ~

    222ms / 128MB
    

    这时限线段树能过?

    可以的。

    正解:裸的 线段树

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <vector>
    using namespace std;
    #define go(i, j, n, k) for (int i = j; i <= n; i += k)
    #define fo(i, j, n, k) for (int i = j; i >= n; i -= k)
    #define rep(i, x) for (int i = h[x]; i; i = e[i].nxt)
    #define mn 1000010
    #define inf 2147483647
    #define ll long long
    #define ld long double
    #define fi first
    #define se second
    #define root 1, n, 1
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    #define bson l, r, rt
    //#define LOCAL
    #define Debug(...) fprintf(stderr, __VA_ARGS__)
    inline int read(){
        int f = 1, x = 0;char ch = getchar();
        while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
        while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    //This is AC head above...
    int n, m, p;
    struct tree{
        ll x;
    };
    struct SegmentTree{ 
        tree z[mn << 2];
        ll col[mn << 2];
        inline void update(int rt){
            z[rt].x = (z[rt << 1].x * z[rt << 1 | 1].x) % p;
        }
        inline tree operation(tree a,tree b){
            return (tree){(a.x * b.x) % p};
        }
        inline void color(int l,int r,int rt,ll v){
            z[rt].x += (r - l + 1) * v;
            col[rt] += v;
        }
        inline void push_col(int l,int r,int rt){
            if(col[rt]){
                int m = (l + r) >> 1;
                color(lson, col[rt]);color(rson, col[rt]);
                col[rt] = 0;
            }
        }
        inline void build(int l,int r,int rt){
            if(l==r){z[rt].x = read();return;}
            int m = (l + r) >> 1;build(lson);build(rson); update(rt);
        }
        inline void modify(int l,int r,int rt,int nowl,int nowr,ll v){
            if(nowl<=l && r<=nowr){color(bson, v); return;}
            int m = (l + r) >> 1; push_col(bson);
            if(nowl<=m) modify(lson, nowl, nowr, v);
            if(m<nowr)  modify(rson, nowl, nowr, v);
            update(rt);
        }
        inline tree query(int l,int r,int rt,int nowl,int nowr){
            if(nowl<=l && r<=nowr) return z[rt];
            int m = (l + r) >> 1; push_col(bson);
            if(nowl<=m){
                if(m<nowr) return operation(query(lson, nowl, nowr), query(rson, nowl, nowr));
                else       return query(lson, nowl, nowr);
            }else          return query(rson, nowl, nowr);
        }
    } tr;
    int main(){
        n = read(), m = read(), p = read();
        tr.build(root);
        go(i, 1, m, 1){
            int l = read(), r = read();
            cout << tr.query(root, l, r).x % p << "
    ";
        } 
    #ifdef LOCAL
        Debug("My Time: %.3lfms
    ", (double)clock() / CLOCKS_PER_SEC);
    #endif
        return 0;
    }
    
    

    为什么不用前缀积?

    题目名字不是前缀积吗?

    我用前缀和思想不行吗?

    如果你用前缀积,那如何实现一个数除以一个数再同余?

    逆元?

    看清楚,30%的数据p为质数,

    也就是说除了这30%,就不保证是不是质数啦!

    不是质数,哪里来的逆元?所以就根本不行的啦。

    为什么不用分块

    O(n sqrt n),,,

    过不过的去1000000你明白的

    为什么不用ST表?

    据大佬说st表的空间卡的厉害,会爆空间

    为什么不用平衡树

    我觉得只有dalao才会这么无聊的用平衡树,,,

    常数啊,,,

    线段树大法好!!!

    upd:道歉,,,我时间卡的过死了,没有注意到评测机的状态

  • 相关阅读:
    Flink Task 并行度
    flink笔记(三) flink架构及运行方式
    Flink笔记(二) DataStream Operator(数据流操作)
    poj 1463 Strategic game
    2014年3月29日小记
    AC自动机学习
    hdu 1028 Ignatius and the Princess III
    hdu 1542 Atlantis
    hdu 1575 Tr A
    hdu 4193 Non-negative Partial Sums
  • 原文地址:https://www.cnblogs.com/yizimi/p/10056289.html
Copyright © 2020-2023  润新知