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;
    }
  • 相关阅读:
    记录百度编辑器bug(在编辑框输入光标到达页面最底部时,功能区块会悬浮在页面最顶部并且与编辑框分离)
    ThinkPHP5实用的数据库操作方法
    Windows10专业工作站版激活方法
    ThinkPHP5验证码不显示的原因及解决方法
    PHPExcel导出工作蒲(多表合并)教程+详细代码解读
    将input file的选择的文件清空的两种解决方案
    微信公众号网页开发——阻止微信客户端内点击任何图片自动放大
    开发中能快速定位错误也是技术的表现,附上【Chrome开发者工具官方中文文档】
    thinkPHP5 报错session_start(): No session id returned by function解决方法
    Linux安装PHPRedis扩展
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5910746.html
Copyright © 2011-2022 走看看