zoukankan      html  css  js  c++  java
  • 二维数据结构学习

    /*
    感觉noip不会靠这些东西..但是碰见了不看看就觉得很别扭,本来想大体知道就行了,背个板,然后 我一下午+一晚上就没干别的QAQ
    先说说线段树吧 处理二维问题的有两种方法 树套树和四叉树
    后者好理解常数小但是不资次打标记(反正我不会~~~)
    后者XXXX常熟大但是资次打标记(我也不会~~~)
    只看看前面那个 树套树嘛 就是在一维的基础上 每个节点都连出一棵树来
    空间复杂度n*n 因为他不支持打标记 所以不能区间改 区间查 
    只能区间改 单点查 或者单点改 区间查
    再啦啦树状数组 同样的 必须扯着一个单点
    区间改的时候 可以向上或者向下更新 查询的时候正好反着
    基础的东西就这么多了 也没准备学的很详细
    */
    
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    /*
    poj 2155
    第一个二维线段树的题
    树套树写法 不支持打标记
    (四叉树支持 然而并不会QAQ) 
    所以这个区间修改就和之前的不大一样
    准确的说这导致只能单点查询
    查单点的时候 把路径上的遇到的标记累加
    因为没有下传 所以都加起来
    还有就是 Query的时候 不是找到x这一行在进入第二层线段树
    而是每个第一层的区间(前提是包含x)都进入第二层y区间找 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1010
    #define lc k*2
    #define rc k*2+1
    #define mid (l+r)/2
    using namespace std;
    int T,n,m,x1,x2,y1,y2,num;
    bool s[maxn*4][maxn*4];
    char c[5];
    void Changey(int kx,int k,int l,int r,int x,int y){
        if(x<=l&&y>=r){
            s[kx][k]=!s[kx][k];
            return;
        }
        if(l==r)return;
        if(x<=mid)Changey(kx,lc,l,mid,x,y);
        if(y>mid)Changey(kx,rc,mid+1,r,x,y);
    }
    void Changex(int k,int l,int r,int x,int y){
        if(x<=l&&y>=r){
            Changey(k,1,1,n,y1,y2);
            return;
        }
        if(l==r)return;
        if(x<=mid)Changex(lc,l,mid,x,y);
        if(y>mid)Changex(rc,mid+1,r,x,y);
    }
    void Queryy(int kx,int k,int l,int r,int x){
        num+=s[kx][k];
        if(l==r)return;
        if(x<=mid)return Queryy(kx,lc,l,mid,x);
        else return Queryy(kx,rc,mid+1,r,x);
    }
    void Queryx(int k,int l,int r,int x){
        Queryy(k,1,1,n,y1);
        if(l==r)return;
        if(x<=mid)return Queryx(lc,l,mid,x);
        else return Queryx(rc,mid+1,r,x);
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n*4;i++)
                for(int j=1;j<=n*4;j++)
                    s[i][j]=0;
            while(m--){
                scanf("%s",c);
                if(c[0]=='C'){
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    Changex(1,1,n,x1,x2);
                }
                else {
                    num=0;
                    scanf("%d%d",&x1,&y1);
                    Queryx(1,1,n,x1);
                    printf("%d
    ",num&1);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    /*
    之前树状数组的了解不全面啊
    一直以为只能单点修改区间查询
    今天又学到了区间修改单点查询
    二维的也是一样
    改的时候用矩形右下角代表整个矩形改没改过
    然后把多改的改回来
    单点查询的时候向下询问 累加 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1010
    using namespace std;
    int T,n,m,x1,x2,y1,y2;
    int s[maxn][maxn];
    char c[5];
    int low(int x){
        return x&(-x);
    }
    void Insert(int x,int y){
        for(int i=x;i>0;i-=low(i))
            for(int j=y;j>0;j-=low(j))
                s[i][j]++;
    }
    int Query(int x,int y){
        int ret=0;
        for(int i=x;i<=n+2;i+=low(i))
            for(int j=y;j<=n+2;j+=low(j))
                ret+=s[i][j];
        return ret;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n+2;i++)
                for(int j=1;j<=n+2;j++)
                    s[i][j]=0;
            while(m--){
                scanf("%s",c);
                if(c[0]=='C'){
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    x1+=2;x2+=2;y1+=2;y2+=2;
                    Insert(x2,y2);Insert(x1-1,y1-1);
                    Insert(x2,y1-1);Insert(x1-1,y2);
                }
                else {
                    scanf("%d%d",&x1,&y1);
                    x1+=2;y1+=2;
                    int num=Query(x1,y1);
                    printf("%d
    ",num&1);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    /*hud1823*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1001
    #define lc k*2
    #define rc k*2+1
    #define mid (l+r)/2
    using namespace std;
    int n=1000,m,x1,y1,x2,y2;
    short int mx[maxn*3][maxn*4],z;
    char c[5];
    void Insert_y(int kx,int k,int l,int r){
        mx[kx][k]=max(mx[kx][k],z);
        if(l==r)return;
        if(y1<=mid)Insert_y(kx,lc,l,mid);
        else Insert_y(kx,rc,mid+1,r);
        mx[kx][k]=max(mx[kx][lc],mx[kx][rc]);
    }
    void Insert_x(int k,int l,int r){
        Insert_y(k,1,0,n);
        if(l==r)return;
        if(x1<=mid)Insert_x(lc,l,mid);
        else Insert_x(rc,mid+1,r);
    }
    int Query_y(int kx,int k,int l,int r){
        if(y1<=l&&y2>=r)return mx[kx][k];
        if(y2<=mid)return Query_y(kx,lc,l,mid);
        else if(y1>mid)return Query_y(kx,rc,mid+1,r);
        else return max(Query_y(kx,lc,l,mid),Query_y(kx,rc,mid+1,r));
    }
    int Query_x(int k,int l,int r){
        if(x1<=l&&x2>=r)return Query_y(k,1,0,n);
        if(x2<=mid)return Query_x(lc,l,mid);
        else if(x1>mid)return Query_x(rc,mid+1,r);
        else return max(Query_x(lc,l,mid),Query_x(rc,mid+1,r));
    }
    int main()
    {
        while(1){
            scanf("%d",&m);
            if(m==0)break;
            memset(mx,-1,sizeof(mx));
            float xi,yi,h1,h2;
            int h;
            while(m--){
                scanf("%s",c);
                if(c[0]=='I'){
                    scanf("%d%f%f",&h,&xi,&yi);
                    x1=h;y1=int(xi*10);z=int(yi*10);
                    Insert_x(1,0,n);
                }
                else {
                    scanf("%f%f%f%f",&h1,&h2,&xi,&yi);
                    x1=int(h1+0.9);x2=int(h2+0.9);
                    y1=int(xi*10);y2=int(yi*10);
                    if(x1>x2)swap(x1,x2);
                    if(y1>y2)swap(y1,y2);
                    int ans=Query_x(1,0,n);
                    if(ans==-1)printf("-1
    ");
                    else printf("%.1f
    ",ans/10.0);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    【win10】浏览器Chrome 和edge 体验对比与使用心得
    【Java】 VM 环境配置过程要点( win10,64位)
    office2013 激活方法
    产品激活 比如Windows激活 , office激活 等激活的原理是什么? KMS等激活工具安全吗?
    回顾外滩踩踏事件,吸取的教训
    【win7】Ubuntu安装使用中的一些注意事项
    黑屏
    mock测试(一)
    Django模型类(一)
    获取本机局域网ip和出口ip
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5910746.html
Copyright © 2011-2022 走看看