士兵杀敌(五)
时间限制: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; }
时间: 2024-10-10 07:48:53