zoukankan      html  css  js  c++  java
  • CF390-E. Inna and Large Sweet Matrix(区间更新+区间查询)

    题意很好理解,不说了

    题解就是每次把值压缩成一维,比如x上,这样就可以求出任意宽度的整个竖条的和。

    如这张图,求的是s5-(s1+s3+s7+s9)

    因为可以求出一整竖条和一整横条,我们可以求出是s2+s5+s8 也可以求出s4+s5+s6 当然也很容易求出总面积S

    那么S-(s2+s5+s8)-(s4+s5+s6) = s1+s3+s7+s9-s5

    对,答案已经出来了,很简单。

    以后看到这种求解公式十分奇怪的题,就要算一算是不是能构造出很简单的公式。

    注意这题用cin cout 会超时!因为codeforce是单样例,所以都忘了这点,t了好多次……T^T

    区间更新+区间查询,线段树+lazy操作 (514ms

    #include <stdio.h>
    
    typedef long long ll;
    
    const int N = 4000005;
    ll tx[N<<2], ty[N<<2], fx[N<<2], fy[N<<2];
    int yl, yr, yv;
    #define lson (o<<1)
    #define rson ((o<<1)+1)
    
    void pushdown(ll tr[], ll fg[], int o, int l, int r)
    {
        if (fg[o]) {
            fg[lson] += fg[o];
            fg[rson] += fg[o];
            int m = (l+r) >> 1;
            tr[lson] += fg[o] * (m-l+1);
            tr[rson] += fg[o] * (r-m);
            fg[o] = 0;
        }
    }
    
    void add(ll tr[], ll fg[], int o, int l, int r)
    {
        if (l == r) {
            tr[o] += yv;
            return ;
        }
        if (yl <= l && yr >= r) {
            tr[o] += (ll)yv * (r-l+1);
            fg[o] += yv;
            return ;
        }
        pushdown(tr, fg, o, l, r);
        int m = (l+r) >> 1;
        if (yl <= m) add(tr, fg, lson, l, m);
        if (yr > m) add(tr, fg, rson, m+1, r);
        tr[o] = tr[lson] + tr[rson];
    }
    
    ll query(ll tr[], ll fg[], int o, int l, int r)
    {
        if (l >= yl && r <= yr) {
            return tr[o];
        }
        pushdown(tr, fg, o, l, r);
        int m = (l+r) >> 1;
        ll ans = 0;
        if (m >= yl) ans += query(tr, fg, o<<1, l, m);
        if (m < yr) ans += query(tr, fg, (o<<1)+1, m+1, r);
        return ans;
    }
    
    
    int main()
    {
    
        int n, m, w;
        scanf("%d%d%d", &n, &m, &w);
        int op;
        int x1, x2, y1, y2;
        ll v;
        ll tot, ans;
        while (w--) {
            scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
            if (op) {
                yl = 1, yr = n;
                tot = query(tx, fx, 1, 1, n);
                ans = 0;
                yl = x1, yr = x2;
                ans += query(tx, fx, 1, 1, n);
                yl = y1, yr = y2;
                ans += query(ty, fy, 1, 1, m);
                printf("%lld
    ", ans-tot);
            } else {
                scanf("%lld", &v);
                yl = x1, yr = x2, yv = v*(y2-y1+1);
                add(tx, fx, 1, 1, n);
                yl = y1, yr = y2, yv = v*(x2-x1+1);
                add(ty, fy, 1, 1, m);
            }
        }
        return 0;
    }

    顺便学习了一下树状数组的区间操作(202ms 时间空间都优于线段树

    #include <stdio.h>
    
    typedef long long ll;
    
    const int MAXN = 4000005;
    
    int lowbit(int x) { return x&-x; }
    
    struct tree_array {
        struct tree_array_single {
            int N; 
            ll arr[MAXN];
            void add(int x, ll v) { while(x <= N) arr[x] += v, x += lowbit(x); }  
            ll sum(int x) { ll sum = 0; while(x) sum+=arr[x], x-=lowbit(x); return sum; }  
        } T1, T2;  
        void add(int x, ll v) { T1.add(x, v); T2.add(x, x*v); }
        void update(int L, int R, ll v) { add(L, v); add(R+1, -v); }
        ll sum(int x) { return (x+1)*T1.sum(x)-T2.sum(x); }
        ll query(int L,int R) { return sum(R)-sum(L-1); }
    } tx, ty;
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        int n, m, w;
        scanf("%d%d%d", &n, &m, &w);
        int op;
        int x1, x2, y1, y2;
        ll v;
        tx.T1.N = tx.T2.N = n;
        ty.T1.N = ty.T2.N = m;
        ll tot = 0;
        while (w--) {
            scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
            if (op) {
                ll ans = tx.query(x1, x2) + ty.query(y1, y2);
                printf("%lld
    ", ans-tot);
            } else {
                scanf("%lld", &v);
                tot += (y2-y1+1)*(x2-x1+1)*v;
                tx.update(x1, x2, v*(y2-y1+1));
                ty.update(y1, y2, v*(x2-x1+1));
            }
        }
        return 0;
    }
  • 相关阅读:
    php网摘收藏
    php优秀网摘
    jquery ajax thinkphp异步局部刷新完整流程
    easyui的accordion为动态生成,accordion的onSelect方法中又动态生成tree,为什么要第二次选择accordion,tree才生成出来
    php导出CSV文件时身份证号码显示为科学计数的解决方法
    php导出数据到excel,防止身份证等数字字符格式变成科学计数的方法
    JQuery实战教程即将面市
    在windows+apache环境下安装ioncube
    PHP长文章分页 实现手动分页代码 代码简单
    DEDE非内容页调用自定义字段使用方法
  • 原文地址:https://www.cnblogs.com/wenruo/p/5787776.html
Copyright © 2011-2022 走看看