zoukankan      html  css  js  c++  java
  • 士兵杀敌5 前缀数组

    士兵杀敌(五)

    时间限制:2000 ms  |  内存限制:65535 KB
    难度:5
     
    描述

    南将军麾下有百万精兵,现已知共有M个士兵,编号为0~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情。

    在这样的情况下,南将军却经常会在许多次战役之后询问军师小工第i号士兵到第j号士兵所有人的总军功数。

    请你帮助军师小工回答南将军的提问。

     
    输入
    只有一组测试数据
    第一行是三个整数N,C,Q(1<=N,C,Q<=1000000),其中N表示士兵的总数。
    随后的C行,每行有三个整数Mi,Ni,Ai(0<=Mi<=Ni<=N,0<=Ai<=100),表示从第Mi号到第Ni号士兵所有人平均增加了Ai的军功。
    再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。
    输出
    请对每次询问输出m号士兵到第n号士兵的总军功数,由于该数值可能太大,请把结果对10003取余后输出
    样例输入
    5 3 2
    1 3 2
    2 4 1
    5 5 10
    1 5
    2 3
    
    样例输出
    19
    6

    线段树代码: 超时
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<sstream>
    #include<algorithm>
    #include<queue>
    #include<deque>
    #include<iomanip>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<stack>
    #include<set>
    #include<fstream>
    #include<memory>
    #include<list>
    #include<string>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    #define MAXN 1000002
    #define L 31
    #define INF 1000000009
    #define eps 0.00000001
    struct node
    {
        int l, r, data;
    }T[MAXN*4+10];
    int n,c,q,a[MAXN];
    /*
    int Query(int p, int k)
    {
        if (T[p].l == T[p].r)
            return T[p].data;
        int mid = (T[p].l + T[p].r) >> 1;
        int sum = T[p].data;
        if (k <= mid)
            sum += Query(p << 1, k);
        else
            sum += Query(p << 1 | 1, k);
        return sum;
    }
    */
    int Query(int p, int l, int r)
    {
        //cout <<":::::::::"<<T[p].l<< ' '<<T[p].r<<' '<<T[p].data << endl;
        if (T[p].l == T[p].r)
            return T[p].data;
        int mid = (T[p].l + T[p].r) >> 1;
        int sum;
        if (l <= T[p].l&&r >= T[p].r)
            sum = (T[p].r - T[p].l + 1)*T[p].data;
        else
            sum = (min(T[p].r, r) - max(T[p].l, l) + 1) * T[p].data;
        if (r <= mid)
            sum += Query(p << 1, l, r);
        else if (l > mid)
            sum += Query(p << 1 | 1, l, r);
        else
        {
            sum += Query(p << 1, l, mid);
            sum += Query(p << 1 | 1, mid + 1, r);
        }
        //cout<<' '<<sum<<endl;
        return sum;
    }
    void Build(int p, int l, int r)
    {
        T[p].l = l, T[p].r = r, T[p].data = 0;
        if (l == r)
        {
            T[p].data = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        Build(p << 1, l, mid);
        Build(p <<1 | 1, mid + 1, r);
    }
    void Insert(int p, int l, int r, int num)
    {
        //cout << p << ' ' << l << ' ' << r << ' ' << num << endl;
        if (l <= T[p].l&&r >= T[p].r)
        {
            T[p].data += num;
            return;
        }
        int mid = (T[p].l + T[p].r) / 2;
        if (r <= mid)
            Insert(p << 1, l, r, num);
        else if (l > mid)
            Insert(p << 1 | 1, l, r, num);
        else
        {
            Insert(p << 1, l, mid, num);
            Insert(p << 1 | 1, mid + 1, r, num);
        }
    }
    int main()
    {
        int t1, t2, t3;
        while (scanf("%d%d%d", &n, &c, &q) != EOF)
        {
            memset(a, 0, sizeof(a));
            Build(1, 1, n);
            while (c--)
            {
                scanf("%d%d%d", &t1, &t2, &t3);
                Insert(1, t1, t2, t3);
            }
            while (q--)
            {
                scanf("%d%d", &t1, &t2);
                printf("%d
    ", Query(1, t1, t2));
            }
        }
        return 0;
    }

    利用前缀数组!巧妙!

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    //#define LOCAL
    const int MAXN = 1000010;
    const int MOD = 10003;
    int m[MAXN];
    int main() {
    #ifdef LOCAL
        freopen("data.in", "r", stdin);
        freopen("data.out", "w", stdout);
    #endif
        int N, C, Q;
        scanf("%d%d%d", &N, &C, &Q);
        memset(m, 0, sizeof(m));
        int a, b, c;
        while (C--) {
            scanf("%d%d%d", &a, &b, &c);
            m[a] += c; m[b + 1] -= c;
        }
        for (int i = 1; i <= N; i++)m[i] += m[i - 1];
        for (int i = 1; i <= N; i++)m[i] = (m[i] + m[i - 1]) % MOD;
        while (Q--) {
            scanf("%d%d", &a, &b);
            printf("%d
    ", (m[b] - m[a - 1] + MOD) % MOD);
        }
        return 0;
    }
  • 相关阅读:
    94、二叉树的中序遍历 | JS
    102、二叉树的层序遍历 | JS
    111、二叉树的最小深度 | JS
    二叉树的先中后序遍历-JS非递归实现
    二叉树的先中后序遍历-JS递归实现
    深度和广度优先遍历-JS实现
    76、最小覆盖子串 | JS-字典
    extra1 二分查找与二叉判定树
    02 线性表的顺序存储
    原型、原型链、作用域、作用域链、闭包
  • 原文地址:https://www.cnblogs.com/joeylee97/p/6875513.html
Copyright © 2011-2022 走看看