zoukankan      html  css  js  c++  java
  • CF438 The Child and Sequence

    题意:

    给定一个长度为n的非负整数序列a,你需要支持以下操作:
    1)给定l,r,输出a[l] + a[l+1] + ... + a[r]

    2)给定l,r,x, 将a[l]、a[l+1]、....、a[r]x取模

    3)给定k,y,将a[k]修改为y

    n, m <= 100000,a[i], x, y <= 109


    对于操作(1)(3)非常简单,线段树基本操作

    问题是操作(2),显然的是我们不能对区间和取模,这样就很难受

    但是我们可以想到,一个数若是比模数小,就不需要取模,而一个数w有效取模次数最多为log(w)

    同时单个数被有效取模的一次只会花费O(logn)

    因此每次修改至多使复杂度增加O(lognlogw)

    这样我们对于区间l, r暴力对每个能取模的数取模即可

    最后时间复杂度为O(mlognlogw)

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define uint unsigned int
     4 #define ull unsigned long long
     5 using namespace std;
     6 const int maxn = 100010;
     7 struct shiki {
     8     ll maxx, sum;
     9 }tree[maxn << 2];
    10 int n, m;
    11 ll a[maxn];
    12 
    13 inline ll read() {
    14     ll x = 0, y = 1;
    15     char ch = getchar();
    16     while(!isdigit(ch)) {
    17         if(ch == '-') y = -1;
    18         ch = getchar();
    19     }
    20     while(isdigit(ch)) {
    21         x = (x << 1) + (x << 3) + ch - '0';
    22         ch = getchar();
    23     }
    24     return x * y;
    25 }
    26 
    27 inline void maintain(int pos) {
    28     int ls = pos << 1, rs = pos << 1 | 1;
    29     tree[pos].maxx = max(tree[ls].maxx, tree[rs].maxx);
    30     tree[pos].sum = tree[ls].sum + tree[rs].sum;
    31 }
    32 
    33 void build(int pos, int l, int r) {
    34     if(l == r) {
    35         tree[pos].maxx = tree[pos].sum = a[l];
    36         return;
    37     }
    38     int mid = l + r >> 1;
    39     build(pos << 1, l, mid);
    40     build(pos << 1 | 1, mid + 1, r);
    41     maintain(pos);
    42 }
    43 
    44 void get_mod(int pos, int L, int R, int l, int r, ll mod) {
    45     if(l > R || r < L) return;
    46     if(tree[pos].maxx < mod) return;
    47     if(l == r) {
    48         tree[pos].sum %= mod;
    49         tree[pos].maxx %= mod;
    50         return;
    51     }
    52     int mid = l + r >> 1;
    53     get_mod(pos << 1, L, R, l, mid, mod);
    54     get_mod(pos << 1 | 1, L, R, mid + 1, r, mod);
    55     maintain(pos);
    56 }
    57 
    58 void update(int pos, int aim, int l, int r, ll val) {
    59     if(l == r && l == aim) {
    60         tree[pos].maxx = tree[pos].sum = val;
    61         return;
    62     }
    63     int mid = l + r >> 1;
    64     if(aim <= mid) update(pos << 1, aim, l, mid, val);
    65     else update(pos << 1 | 1, aim, mid + 1, r, val);
    66     maintain(pos);
    67 }
    68 
    69 ll query_sum(int pos, int L, int R, int l, int r) {
    70     if(l > R || r < L) return 0;
    71     if(l >= L & r <= R) return tree[pos].sum;
    72     int mid = l + r >> 1;
    73     return query_sum(pos << 1, L, R, l, mid) + query_sum(pos << 1 | 1, L, R, mid + 1, r); 
    74 }
    75 
    76 int main() {
    77     n = read(), m = read();
    78     for(int i = 1; i <= n; ++i) a[i] = read();
    79     build(1, 1, n);
    80     for(int i = 1; i <= m; ++i) {
    81         int opt = read(), x = read(), y = read();
    82         if(opt == 1) printf("%I64d
    ", query_sum(1, x, y, 1, n));
    83         if(opt == 2) {
    84             ll p = read();
    85             get_mod(1, x, y, 1, n, p); 
    86         }
    87         if(opt == 3) update(1, x, 1, n, y);
    88     } 
    89     return 0;
    90 }
  • 相关阅读:
    Docker部署Mysql实践
    Docker部署Zookeeper部署集群实践(2)
    Docker部署Zookeeper部署实践(1)
    Docker部署Jenkins 2.285版持续部署集成实践(1)
    Ubuntu18.04安装docker
    Git的配置
    C语言的一些小知识
    线段树模板整理
    关于Kmp
    HDU-2063(二分图匹配模板题)
  • 原文地址:https://www.cnblogs.com/ywjblog/p/10391075.html
Copyright © 2011-2022 走看看