HDU 5828 Rikka with Sequence(线段树+小优化)

来源:互联网 发布:华讯网络校园招聘待遇 编辑:程序博客网 时间:2024/06/03 13:52

Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has an array A with n numbers. Then he makes m operations on it.

There are three type of operations:

1 l r x : For each i in [l,r], change A[i] to A[i]+x
2 l r : For each i in [l,r], change A[i] to ⌊A−−√[i]⌋
3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]

It is too difficult for Rikka. Can you help her?

Input
The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.

For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.

It is guaranteed that 1<=A[i],x<=100000.

Output
For each operation of type 3, print a lines contains one number – the answer of the query.

Sample Input
1
5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5

Sample Output
5
6

两个基本线段树题的融合,成段更新+hdu4027,坑点在于这个开根号到1之后还会有加的操作,如果单纯像4027那样只对一个是否区间都为1剪枝会超时,增加剪枝:

区间内数都为1后,再有操作时区间内数字都相同,也就是当某区间内值都相同时,各种操作可以只算到这层,然后把lazy标记向下推一层;

参考网上大神完善了代码,比赛时并没能想出来怎么优化TAT。。。好菜啊。。。

ac代码:

#include <bits/stdc++.h>using namespace std;#define rep(i,a,n) for(int i = (a); i < (n); i++)#define per(i,a,n) for(int i = (n)-1; i >= (a); i--)#define clr(arr,val) memset(arr, val, sizeof(arr))#define mp make_pair#define pb push_back#define fi first#define se second#define pi acos(-1)typedef pair<int, int> pii;typedef long long LL;const double eps = 1e-8;const int mod = 1000000007;#define lson l,mid,rt*2#define rson mid+1,r,rt*2+1const int maxn = 100005;LL sum[maxn<<2], laz[maxn<<2];LL mark[maxn<<2];void PushUp(int rt){    sum[rt] = sum[rt<<1] + sum[rt<<1|1];    if(mark[rt<<1] == mark[rt<<1|1])        mark[rt] = mark[rt<<1];    else mark[rt] = 0;    return ;}void pushdown(int rt, int len){    if(mark[rt]){        mark[rt<<1] = mark[rt<<1|1] = mark[rt];        sum[rt<<1] = mark[rt]*(len-len/2);        sum[rt<<1|1] = mark[rt]*(len/2);        laz[rt] = 0;    }    if(laz[rt]){        laz[rt<<1] += laz[rt];        laz[rt<<1|1] += laz[rt];        sum[rt<<1] += laz[rt]*(len-len/2);        sum[rt<<1|1] += laz[rt]*(len/2);        if(mark[rt<<1]) mark[rt<<1] += laz[rt];        if(mark[rt<<1|1]) mark[rt<<1|1] += laz[rt];        laz[rt] = 0;    }}void build(int l, int r, int rt){    laz[rt] = 0;    mark[rt] = 0;    if(l == r){        scanf("%I64d", &sum[rt]);        mark[rt] = sum[rt];        return ;    }    int mid = (l+r)>>1;    build(lson);    build(rson);    PushUp(rt);}void add(int L,int R,LL c,int l,int r,int rt){    if(L <= l && R >= r){        sum[rt] += c*(r-l+1);        laz[rt] += c;        if(mark[rt]) mark[rt] += c;        return;    }    pushdown(rt, r-l+1);    int mid = (l+r)>>1;    if(L<=mid)        add(L,R,c,lson);    if(mid < R)        add(L,R,c,rson);    PushUp(rt);    return ;}void sq(int L, int R, int l, int r, int rt){    if(L <= l && R >= r && mark[rt]){        mark[rt] = (LL)sqrt(mark[rt]);        sum[rt] = mark[rt]*(r-l+1);        return ;    }    pushdown(rt, r-l+1);    int mid = (l+r)>>1;    if(L <= mid) sq(L, R, lson);    if(mid < R) sq(L, R, rson);    PushUp(rt);    return ;}LL query(int L, int R, int l, int r, int rt){    if(L <= l && r <= R){        return sum[rt];    }    pushdown(rt, r-l+1);    int mid = (l+r)>>1;    LL ans = 0;    if(L <= mid) ans += query(L, R, lson);    if(mid < R) ans += query(L, R, rson);    return ans;}int main(int argc, char const *argv[]) {    int n, m;    int t;    scanf("%d", &t);    while(t--){        scanf("%d%d", &n, &m);        build(1, n, 1);        int a, x, y;        LL num;        while(m--){            scanf("%d%d%d", &a, &x, &y);            if(a == 1){                scanf("%I64d", &num);                add(x, y, num, 1, n, 1);            }            if(a == 2)                sq(x, y, 1, n, 1);            if(a == 3)                printf("%I64d\n", query(x, y, 1, n, 1));        }    }    return 0;}
0 0
原创粉丝点击