• $[SHOI2007]$ 园丁的烦恼 二维数点/树状数组


    (Sol)

    设一个矩阵的左上角为((x_1,y_1)),右下角为((x_2,y_2)),(s_{x,y})是到((1,1))二维前缀和,那么这个矩阵的答案显然是(s_{x_2,y_2}-s_{x_1-1,y_2}-s_{x_2,y_1-1}+s_{x_1-1,x_2-1}).考虑把每个询问拆成这么四个二维前缀和的询问.将所有询问的(s_{x,y})按照(x)排序,依次计算,这样我们就可以忽略(x)的限制而只考虑(y)的限制了.每次扫到一个询问,先把(x)不大于该询问的(x)的点加入集合,于是只要查询集合中(y)不大于该询问(y)的点数即可.以(y)为下标维护一个树状数组.

    写了超级久(.jpg),最开始没有把询问坐标离散化,竟然还获得了(50pts),对拍拍了好久发现(make)里没写(srand(time(0))),最后终于写对了,交上去没删注释又(WA)了一波 : (

    (Code)

    #include<bits/stdc++.h>
    #define il inline
    #define Ri register int
    #define go(i,a,b) for(Ri i=a;i<=b;++i)
    #define yes(i,a,b) for(Ri i=a;i>=b;--i)
    #define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define db double
    #define inf 2147483647
    using namespace std;
    il int read()
    {
        Ri x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    const int N=500005;
    int n,m,b[N*4],ct,t[N*4],as[N];
    struct nd{int x,y;}a[N];
    struct qqq{int x1,y1,x2,y2;}qq[N];
    struct que{int x,y,id,fl;}q[N*4];
    il bool cmp(nd x,nd y){return x.x<y.x;}
    il bool cmp1(que x,que y){return x.x<y.x;}
    il int get(Ri x){return lower_bound(b+1,b+ct+1,x)-b;}
    il int lowbit(Ri x){return x&(-x);}
    il void add(Ri x){while(x<=ct){++t[x];x+=lowbit(x);}}
    il int sum(Ri x){Ri ret=t[x];while(x>0){x-=lowbit(x),ret+=t[x];}return ret;}
    int main()
    {
        n=read(),m=read();
        go(i,1,n){Ri x=read(),y=read();a[i]=(nd){x,y};b[++ct]=x,b[++ct]=y;}
        go(i,1,m){Ri x1=read(),y1=read(),x2=read(),y2=read();b[++ct]=x1,b[++ct]=x2,b[++ct]=y1,b[++ct]=y2;qq[i]=(qqq){x1,y1,x2,y2};}
        sort(b+1,b+ct+1);ct=unique(b+1,b+ct+1)-(b+1);
        go(i,1,n)a[i].x=get(a[i].x),a[i].y=get(a[i].y);
        go(i,1,m)
        {
    	    Ri x1=get(qq[i].x1),y1=get(qq[i].y1),x2=get(qq[i].x2),y2=get(qq[i].y2);
    	    q[i]=(que){x1-1,y1-1,i,1};q[i+m]=(que){x1-1,y2,i,-1};
    	    q[i+m*2]=(que){x2,y1-1,i,-1};q[i+m*3]=(que){x2,y2,i,1};
        }
        sort(a+1,a+n+1,cmp);sort(q+1,q+m*4+1,cmp1);Ri cur=1;
        go(i,1,m*4)
        {
    	    while(cur<=n && a[cur].x<=q[i].x)add(a[cur].y),++cur;
    	    as[q[i].id]+=q[i].fl*sum(q[i].y);
        }
        go(i,1,m)printf("%d
    ",as[i]);
        return 0;
    }
    
    
    
  • 相关阅读:
    c# vs2010 excel 上传oracle数据
    Viola-Jones人脸检測
    apache commons-configuration包读取配置文件
    linux 读取文件
    linux 统计某个文件的行数
    linux 判空处理
    linux 查看某个目录下文件的数量
    nginx 配置文件正确性测试
    使用postman上传excel文件测试导入excel
    java 反射获取字段为List类型中的泛型类型
  • 原文地址:https://www.cnblogs.com/forward777/p/11742379.html
Copyright © 2020-2023  润新知