1. 程式人生 > >士兵殺敵5 前綴數組

士兵殺敵5 前綴數組

max sstream 內存 pan ios log pri insert truct

士兵殺敵(五)

時間限制: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\n", 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\n", (m[b] - m[a - 1] + MOD) % MOD);
    }
    return 0;
}

士兵殺敵5 前綴數組