zoukankan      html  css  js  c++  java
  • POJ 3468 A Simple Problem with Integers

    POJ_3468

        现在用的方法还是比较慢的,因为YTQ给我那个PPT还没深入研究透,PPT上面对这种的题的解法是用维护前缀和的前缀和以及{n*An}的前缀和来实现的,而我用的方法就是比较朴素的做lazy标记,来标识该区间内每个元素增加了多少。如果需要查询子区间时,再更新子区间的和,并将lazy标记传递下去。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 100010
    int N, M, Q;
    long long int tree[4 * MAXD], lazy[4 * MAXD], res;
    int left[4 * MAXD], right[4 * MAXD], num[4 * MAXD];
    char op[5];
    void init()
    {
    int i, j;
    for(M = 1; M < N + 2; M <<= 1);
    memset(tree, 0, sizeof(tree));
    memset(lazy, 0, sizeof(lazy));
    for(i = 0, j = M + 1; i < N; i ++, j ++)
    scanf("%lld", &tree[j]);
    for(i = M, j = 0; i < 2 * M; i ++, j ++)
    {
    left[i] = right[i] = j;
    if(j >= 1 && j <= N)
    num[i] = 1;
    else
    num[i] = 0;
    }
    for(i = M - 1; i > 0; i --)
    {
    tree[i] = tree[2 * i] + tree[2 * i + 1];
    num[i] = num[2 * i] + num[2 * i + 1];
    left[i] = left[2 * i];
    right[i] = right[2 * i + 1];
    }
    }
    void add(int cur, int &a, int &b, int &c)
    {
    int i, k;
    if(lazy[cur] && cur < M)
    {
    lazy[2 * cur] += lazy[cur];
    lazy[2 * cur + 1] += lazy[cur];
    tree[2 * cur] += lazy[cur] * num[2 * cur];
    tree[2 * cur + 1] += lazy[cur] * num[2 * cur + 1];
    lazy[cur] = 0;
    }
    if(left[cur] >= a && right[cur] <= b)
    {
    k = c * num[cur];
    tree[cur] += k;
    lazy[cur] = c;
    for(i = cur; i ^ 1; i >>= 1)
    tree[i >> 1] += k;
    return ;
    }
    if(left[2 * cur] <= b && right[2 * cur] >= a)
    add(2 * cur, a, b, c);
    if(left[2 * cur + 1] <= b && right[2 * cur + 1] >= a)
    add(2 * cur + 1, a, b, c);
    }
    void make(int cur, int &a, int &b)
    {
    int i, k;
    if(lazy[cur] && cur < M)
    {
    lazy[2 * cur] += lazy[cur];
    lazy[2 * cur + 1] += lazy[cur];
    tree[2 * cur] += lazy[cur] * num[2 * cur];
    tree[2 * cur + 1] += lazy[cur] * num[2 * cur + 1];
    lazy[cur] = 0;
    }
    if(left[cur] >= a && right[cur] <= b)
    {
    res += tree[cur];
    return ;
    }
    if(left[2 * cur] <= b && right[2 * cur] >= a)
    make(2 * cur, a, b);
    if(left[2 * cur + 1] <= b && right[2 * cur + 1] >= a)
    make(2 * cur + 1, a, b);
    }
    void solve()
    {
    int i, j, a, b, c, s, t;
    scanf("%s", op);
    if(op[0] == 'C')
    {
    scanf("%d%d%d", &a, &b, &c);
    add(1, a, b, c);
    }
    else
    {
    scanf("%d%d", &a, &b);
    res = 0;
    make(1, a, b);
    printf("%lld\n", res);
    }
    }
    int main()
    {
    while(scanf("%d%d", &N, &Q) == 2)
    {
    init();
    for(int i = 0; i < Q; i ++)
    solve();
    }
    return 0;
    }


  • 相关阅读:
    前端战五渣学前端——跨域
    CSS3学习笔记
    Vue工程化入口文件main.js中Vue.config.productionTip = false含义
    CSS选择器有哪几种?举例轻松理解CSS选择器
    研究生综合英语 作文 作业
    tomcat部署项目的方法
    【Winfrom-无边框窗体】Winform如何拖动无边框窗体?
    C#调用默认浏览器打开网页的几种方法
    CefSharp在高DPI的屏幕上出现黑边(winform)
    c# 关于mongo bson转json的问题
  • 原文地址:https://www.cnblogs.com/staginner/p/2230920.html
Copyright © 2011-2022 走看看