zoukankan      html  css  js  c++  java
  • P4514 上帝造题的七分钟

    传送门

    看到题目一眼 $cdq$ 分治,然后发现 $n,m$ 很小,感到一丝不对劲

    然后去看看题解发现正解是二维树状数组

    二维树状数组和一维的好像也差不多?

    struct BIT {
        int t[N][N];
        inline void add(int x,int y,int v)
        {
            for(;x<=n;x+=x&-x)
                for(int j=y;j<=m;j+=j&-j) t[x][j]+=v;
        }
        inline int ask(int x,int y)
        {
            int res=0;
            for(;x;x-=x&-x)
                for(int j=y;j;j-=j&-j) res+=t[x][j];
            return res;
        }
    };
    二维BIT

    题目要求的是矩形修改矩形询问,考虑差分并用差分数组求原数组二维前缀和再容斥一下,设差分矩阵为 $A$

    那么对于一个二维前缀和的询问 $(x,y)$ ,差分矩阵某个位置 $(a,b),a leq x,b leq y$ 被统计当且仅当 $x' leq x,y' leq y$ 并且 $a leq x' ,b leq y'$ 

    显然这样的 $(x',y')$ 有 $(x-a+1)*(y-b+1)$ 对,那么这个位置 $(a,b)$ 就会被统计到 $(x-a+1)*(y-b+1)$ 次,所以贡献为 $A[a][b]*(x-a+1)*(y-b+1)$

    把后面拆开 $(xy-xb+x-ay+ab-a+y-b+1)=(xy+x+y+1)-(x+1)b-(y+1)a+ab$

    所以对于二维前缀和的询问 $(x,y)$ 我们只要开四个树状数组分别维护 $A[a][b],A[a][b]*b,A[a][b]*a,A[a][b]*ab$ 即可

    最后容斥一下就是答案了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2049,M=2e5+7;
    int n,m;
    struct BIT {
        int t[N][N];
        inline void add(int x,int y,int v)
        {
            for(;x<=n;x+=x&-x)
                for(int j=y;j<=m;j+=j&-j) t[x][j]+=v;
        }
        inline int ask(int x,int y)
        {
            int res=0;
            for(;x;x-=x&-x)
                for(int j=y;j;j-=j&-j) res+=t[x][j];
            return res;
        }
    }T,Ti,Tj,Tij;
    inline void ADD(int x,int y,int v)
    {
        T.add(x,y,v); Ti.add(x,y,v*x);
        Tj.add(x,y,v*y); Tij.add(x,y,v*x*y);
    }
    inline int ASK(int x,int y)
    {
        return T.ask(x,y)*(x*y+x+y+1)+Tij.ask(x,y)
                -Ti.ask(x,y)*(y+1)-Tj.ask(x,y)*(x+1);
    }
    int main()
    {
        char s[7]; scanf("%s",s); n=read(),m=read();
        int a,b,c,d,v;
        while(scanf("%s",s)!=EOF)
        {
            a=read(),b=read(),c=read(),d=read();
            if(s[0]=='L')
            {
                v=read(); ADD(a,b,v); ADD(c+1,d+1,v);
                ADD(a,d+1,-v); ADD(c+1,b,-v);
            }
            else printf("%d
    ",ASK(a-1,b-1)+ASK(c,d)-ASK(a-1,d)-ASK(c,b-1));
        }
        return 0;
    }
  • 相关阅读:
    iOS下JS与OC互相调用(三)--MessageHandler
    在xcode6中使用矢量图(iPhone6置配UI)
    UITextField增加textDidChange回调功能
    IOS开发之格式化日期时间(转)
    ios中将事件同步到系统日历
    xcode中一些便捷用法@literals简写
    JavaScript
    fuzz for test of the Net::HTTP::GET
    perl6 中将 字符串 转成十六进制
    Net::HTTP 一次添加 cookie, body 发送post请求
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11505738.html
Copyright © 2011-2022 走看看