codeforces 895E

(+2 lazy tree line marks)
meaning of the questions: give fixed n(n<105) Digit ai(ai<109) , Then give q(q<105) Operations, the operation of two types, a. In these figures [l1,r1] Interval and any of a number [l2,r2] Any digital switching interval. 2. seek [l,r] All the numbers and range (mathematical expectation)

Thinking: Interval modify and query the array, with the thought segment tree, where each node of the tree maintenance segment three values: the sum of the mathematical expectation, addition and multiplication tag marking. why? If an operation is given a title, then for [l1,r1] Interval of a number x, the 1 after the operation, it becomes a mathematical expectation xr1l1r1l1+1+in = r 2I = l' 2air2l2+11r1l1+1 (Left for the desired item numbers are not exchanged, the right term is expected to be exchanged). Here we note that the operation 1:00, [l1,r1] Where the mathematical expectation is not the same, because multiplication and division aimed at this interval in each particular digital, rather than the whole range (it is necessary to maintain the addition and multiplication mark mark)

Code:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define lson p<<1,l,mid
#define rson p<<1|1,mid+1,r

using namespace std;
const int maxn = 100050;
const double eps = 1e-6;

double a[maxn], sum[maxn<<2];
double addv[maxn<<2], multv[maxn<<2];

int dcmp(double x) {
    if(fabs(x) < eps) return 0;
    return (x < 0 ? -1:1);
}

void push_up(int p) {
    sum[p] = sum[p<<1] + sum[p<<1|1];
}

/** lazy tags are designed for the lower nodes. **/
void push_down(int p, int l, int r) {
    if(dcmp(multv[p])!=1 || dcmp(addv[p])!=0) {
        multv[p<<1] *= multv[p];
        multv[p<<1|1] *= multv[p];
        addv[p<<1] = multv[p]*addv[p<<1] + addv[p];
        addv[p<<1|1] = multv[p]*addv[p<<1|1] + addv[p];
        int mid = (l+r) >> 1;
        sum[p<<1] = multv[p]*sum[p<<1] + addv[p]*(mid-l+1);
        sum[p<<1|1] = multv[p]*sum[p<<1|1] + addv[p]*(r-mid);
        multv[p] = 1; addv[p] = 0;
    }
}

void build(int p, int l, int r) {
    multv[p] = 1; addv[p] = 0;
    if(l == r) {
        sum[p] = a[l];
        return ;
    }
    int mid = (l+r) >> 1;
    build(lson); build(rson);
    push_up(p);
}

/** y = k*x + b; **/
void modify(int p, int l, int r, int L, int R, double k, double b) {
    if(L <= l && r <= R) {
        sum[p] = k*sum[p] + b*(r-l+1);
        multv[p] *= k;
        addv[p] = k*addv[p] + b;
        return ;
    }
    push_down(p, l, r);
    int mid = (l+r) >> 1;
    if(L <= mid) modify(lson, L, R, k, b);
    if(R > mid) modify(rson, L, R, k, b);
    push_up(p);
}

double query(int p, int l, int r, int L, int R) {
    if(L <= l && r <= R)
        return sum[p];
    push_down(p, l, r);
    double ret = 0;
    int mid = (l+r) >> 1;
    if(L <= mid) ret += query(lson, L, R);
    if(R > mid) ret += query(rson, L, R);
    return ret;
}

int main() {
    //freopen("test.txt","r",stdin);
    int n, q;
    scanf("%d%d",&n,&q);
    for(int i=1; i<=n; i++)
        scanf("%lf",&a[i]);
    build(1, 1, n);
    while(q --) {
        int op, l1, r1, l2, r2;
        scanf("%d",&op);
        if(op == 1) {
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            double size1 = r1 - l1 + 1, size2 = r2 - l2 + 1;
            double t1 = query(1, 1, n, l1, r1), t2 = query(1, 1, n, l2, r2);
            //printf("query t1: %f t2:%f\n",t1,t2);
            modify(1, 1, n, l1, r1, (size1-1)/size1, t2/(size2*size1));
            modify(1, 1, n, l2, r2, (size2-1)/size2, t1/(size1*size2));
        }
        else {
            scanf("%d%d",&l1,&l2);
            double ans = query(1, 1, n, l1, l2);
            printf("%f\n",ans);
        }
    }
    return 0;
}
发布了40 篇原创文章 · 获赞 44 · 访问量 9万+

Guess you like

Origin blog.csdn.net/Site1997/article/details/78701117