您的位置:首页 > 其它

Codeforces Round#179(Div 2)C Greg and Array

2013-04-12 11:09 309 查看
题目链接:http://codeforces.com/problemset/problem/295/A

我果断想错了时间复杂度,所以就没敲出来。

有两种解法,一种是线段树,两棵线段树,一棵维护每种指令用了多少次,一棵维护每段被怎么更新,时间复杂度都是nlogn级别的,可是我算错了五个数量级,昨天晚上比赛没敢写……

另一种方法是扫描法,O(n)级别,很简单,编码复杂度也比线段树解法小得多。

//扫描法
#include <cstdio>
#define LL long long
const int maxn = 100100;
LL a[maxn], b[maxn], d[maxn], ll[maxn], rr[maxn], c[maxn];
int l, r, n, m, k;
int main(){
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++) scanf("%I64d", &a[i]);
for (int i = 1; i <= m; i++) scanf("%I64d%I64d%I64d", &ll[i], &rr[i], &d[i]);
for (int i = 1; i <= k; i++){
scanf("%d%d", &l, &r);
c[l - 1] += 1; c[r] -= 1;
}
LL t = 0;
for (int i = 0; i <= m; i++){
d[i] *= t;
t += c[i];
}
t = 0;
for (int i = 0; i <= m; i++){
b[ll[i] - 1] += d[i];
b[rr[i]] -= d[i];
}
for (int i = 0; i <= n; i++){
a[i] += t; t += b[i];
}
for (int i = 1; i<= n; i++) printf("%I64d ", a[i]);
printf("\n");
return 0;
}
//线段树法
#include <cstdio>
#include <cstring>
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define LL long long
const int maxn = 101000;
struct seg{
LL sum[maxn << 2], add[maxn << 2];
void PushUp(int rt){
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void PushDown(int rt, int m){
if (add[rt]){
add[rt << 1] += add[rt];
add[rt << 1 | 1] += add[rt];
sum[rt << 1] += add[rt] * (m - (m >> 1));
sum[rt << 1 | 1] += add[rt] * (m >> 1);
add[rt] = 0;
}
}
void build(int l, int r, int rt){
add[rt] = 0;
if (l == r){
scanf("%I64d", &sum[rt]);
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int ll, int rr, LL c, int l, int r, int rt){
if (ll <= l && rr >= r){
sum[rt] += c * (r - l + 1);
add[rt] += c;
return;
}
PushDown(rt, r - l + 1);
int m = (l + r) >> 1;
if (ll <= m) update(ll, rr, c, lson);
if (rr > m) update(ll, rr, c, rson);
PushUp(rt);
}
LL query(int x, int l, int r, int rt){
if (l == r) return sum[rt];
PushDown(rt, r - l + 1);
int m = (l + r) >> 1;
if (x <= m) return query(x, lson);
else return  query(x, rson);
}
};
struct chg{
int l, r;
LL d;
void get(){
scanf("%d%d%I64d", &l, &r, &d);
}
}x[maxn];
seg a, b;
int main(){
int n, m, k;
while (~scanf("%d%d%d", &n, &m, &k)){
a.build(1, n, 1);
memset(b.sum, 0, sizeof(b.sum));
memset(b.add, 0, sizeof(b.add));
for (int i = 1; i <= m; i++) x[i].get();
for (int i = 1; i <= k; i++){
int l, r;
scanf("%d%d", &l, &r);
b.update(l, r, 1, 1, m, 1);
}
for (int i = 1; i <= m; i++){
LL tt = b.query(i, 1, m, 1);
a.update(x[i].l, x[i].r, x[i].d * tt, 1, n, 1);
}
for (int i = 1; i <= n; i++){
LL ans = a.query(i, 1, n, 1);
printf("%I64d ", ans);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: