zoukankan      html  css  js  c++  java
  • Wannafly Winter Camp 2020 Day 5I Practice for KD Tree

    给定一个 (n imes n) 矩阵,先进行 (m_1 leq 5e4) 次区间加,再进行 (m_2 leq 5e5) 次询问,每次询问要求输出矩形区间内的最大数。(n leq 2000)

    Solution

    考虑到 (n) 比较小,可以直接二位差分前缀和搞出整个矩阵。

    然后一本正经地扔进二维线段树

    二维线段树怎么写来着?

    卡常致死

    返回值慢得让人恶心

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    
    int n;
    ll val[18000005],a[2005][2005];
    
    int m1,m2;
    
    void build(int p,int xl,int xr,int yl,int yr,int fg) {
        if(xl>xr || yl>yr) return;
        if(xl==xr && yl==yr) {
            val[p]=a[xl][yl];
        }
        else if(fg) {
            build(p<<1,xl,(xl+xr)>>1,yl,yr,fg^1);
            build(p<<1|1,((xl+xr)>>1)+1,xr,yl,yr,fg^1);
            val[p]=max(val[p<<1],val[p<<1|1]);
        }
        else {
            build(p<<1,xl,xr,yl,(yl+yr)>>1,fg^1);
            build(p<<1|1,xl,xr,((yl+yr)>>1)+1,yr,fg^1);
            val[p]=max(val[p<<1],val[p<<1|1]);
        }
    }
    
    ll tmp;
    int qxl,qxr,qyl,qyr;
    
    void query(int p,int xl,int xr,int yl,int yr,int fg) {
        if(val[p]<tmp) return;
        if(xl>qxr || xr<qxl || yl>qyr || yr<qyl) return;
        if(xl>=qxl && xr<=qxr && yl>=qyl && yr<=qyr) tmp=max(tmp,val[p]);
        else if(fg) {
            query(p<<1,xl,(xl+xr)>>1,yl,yr,fg^1);
            query(p<<1|1,((xl+xr)>>1)+1,xr,yl,yr,fg^1);
        }
        else {
            query(p<<1,xl,xr,yl,(yl+yr)>>1,fg^1);
            query(p<<1|1,xl,xr,((yl+yr)>>1)+1,yr,fg^1);
        }
    }
    
    ll calc(int x1,int y1,int x2,int y2) {
        tmp=0;qxl=x1;qxr=x2;qyl=y1;qyr=y2;
        query(1,1,n,1,n,1);
        return tmp;
    }
    
    signed main() {
        scanf("%d%d%d",&n,&m1,&m2);
        for(int i=1;i<=m1;i++) {
            int x1,y1,x2,y2,w;
            scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&w);
            a[x1][y1]+=w;
            a[x1][y2+1]-=w;
            a[x2+1][y1]-=w;
            a[x2+1][y2+1]+=w;
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
                a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
            }
        }
        build(1,1,n,1,n,1);
        for(int i=1;i<=m2;i++) {
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            printf("%lld
    ",calc(x1,y1,x2,y2));
        }
    }
    
    
  • 相关阅读:
    Spring配置多个数据源
    虚拟机内存结构
    Java中sleep,wait,yield,join的区别
    Java的四种引用方式
    Java 中的泛型详解-Java编程思想
    Java RTTI和反射
    linux 分析java 线程状态
    小容量的byteBuffer 读取大文本
    @Conditional 原理
    替换字符串占位符
  • 原文地址:https://www.cnblogs.com/mollnn/p/12342681.html
Copyright © 2011-2022 走看看