zoukankan      html  css  js  c++  java
  • bzoj2683&&bzoj4066

    题解:

    前一题不是强制在线,后一题是强制在线

    树套树空间会炸

    说一下cdq分治+树状数组

    首先我们利用cdq分治使得查询和操作保证先后关系

    然后矩阵查询变成4个矩阵的差

    那么我们就可以运用扫描线的方法来维护了

    时间nlogn^2,空间O(n)

    后一题是kd-tree

    查询的方法和线段树基本一样

    如果矩阵被包含就返回答案,如果不被包含就直接退出

    否则递归下去

    然后修改的话和替罪羊树一样

    达到一定时候就重构

    注意一下x相同insert和build要保证y的顺序区分左右

    另外学习了一下map中用struct作为key的方法 虽然这题完全不用用

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int 
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define mid ((h+t)/2)
    #define me(x) memset(x,0,sizeof(x))
    const int INF=2e9;
    const int N=6e6+1e4;
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
      return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T>void read(T &x)
    {
      rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
      while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
    }
    IL void umax(int &x,int y)
    {
      if (x<y) x=y;
    }
    IL void umin(int &x,int y)
    {
      if (x>y) x=y;
    }
    struct re{
      int d[2],v;
    }p[N];
    int cmp_d,ans,rt,num;
    bool cmp(re x,re y)
    {
      return x.d[cmp_d]<y.d[cmp_d]||(x.d[cmp_d]==y.d[cmp_d]&&x.d[cmp_d^1]<y.d[cmp_d^1]);
    }
    struct kd
    {
      int Mx[N],My[N],Nx[N],Ny[N],count2[N],ls[N],rs[N];
      IL void clear()
      {
        me(count2);
        me(ls); me(rs);
      }
      IL void updata(int x)
      {
        count2[x]=count2[ls[x]]+count2[rs[x]]+p[x].v;
        if (ls[x])
        {
          umax(Mx[x],Mx[ls[x]]);
          umax(My[x],My[ls[x]]);
          umin(Nx[x],Nx[ls[x]]);
          umin(Ny[x],Ny[ls[x]]);
        }
        if (rs[x])
        {
          umax(Mx[x],Mx[rs[x]]);
          umax(My[x],My[rs[x]]);
          umin(Nx[x],Nx[rs[x]]);
          umin(Ny[x],Ny[rs[x]]);
        }
      }
      int build(int h,int t,int o)
      {
        cmp_d=o; nth_element(p+h,p+mid,p+t+1,cmp);
        int x=mid;
        Mx[x]=Nx[x]=p[x].d[0];
        My[x]=Ny[x]=p[x].d[1];
        count2[x]=p[x].v;
        if (h!=x) ls[x]=build(h,mid-1,o^1); else ls[x]=0;
        if (x!=t) rs[x]=build(mid+1,t,o^1); else rs[x]=0;
        updata(x);
        return x; 
      }
      void insert(int &k,int x,int y,int z,int o)
      {
        if (!k)
        {
          k=++num;
          Mx[num]=Nx[num]=p[num].d[0];
          My[num]=Ny[num]=p[num].d[1];
          count2[num]=p[num].v=z;
          return;
        }
        if (p[k].d[0]==x&&p[k].d[1]==y)
        {
          count2[k]+=z; p[k].v+=z; return;
        }
        if (!o)
          if (x<p[k].d[0]||(x==p[k].d[0]&&y<p[k].d[1])) insert(ls[k],x,y,z,o^1);
          else insert(rs[k],x,y,z,o^1);
        else if (y<p[k].d[1]||(y==p[k].d[1]&&x<p[k].d[0])) insert(ls[k],x,y,z,o^1);
          else insert(rs[k],x,y,z,o^1); 
        updata(k);
      }
      void query(int k,int x1,int x2,int y1,int y2)
      {
        if (!k||Mx[k]<x1||Nx[k]>x2||My[k]<y1||Ny[k]>y2) return;
        if (x2>=Mx[k]&&Nx[k]>=x1&&y2>=My[k]&&Ny[k]>=y1)
        {
          ans+=count2[k]; return;
        }
        if (x1<=p[k].d[0]&&p[k].d[0]<=x2&&y1<=p[k].d[1]&&p[k].d[1]<=y2)
          ans+=p[k].v;
        query(ls[k],x1,x2,y1,y2); query(rs[k],x1,x2,y1,y2);
      }
    }kd;
    struct re1{
      int a,b;
    };
    struct cmp2
    {
      bool operator() (const re1 x,const re1 y)
      {
        if (x.a<y.a||(x.a==y.a&&x.b<y.b)) return(1); else return(0);
      }
    };
    map<re1,int,cmp2> M;
    int main()
    {
      int m;
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      read(m);
      int cnt=0,rt=0,i=0;
      while (1)
      {
        i++;
        ans=0;
        int k;
        read(k);
        if (k==3) break;
        if (k==1)
        {
          int x,y,z;
          read(x); read(y); read(z);
          x^=ans; y^=ans; z^=ans;
          re1 k3=(re1){x,y};
          int kk=M[k3];
          if (!kk) p[num+1].d[0]=x,p[num+1].d[1]=y,kk=num+1;
          M[k3]=kk;
          kd.insert(rt,x,y,z,0);
          cnt++;
          if (cnt%10000==0)
          { 
            kd.clear();
            rt=kd.build(1,num,0);
          } 
        } else
        {
          int x1,x2,y1,y2;
          read(x1),read(y1),read(x2),read(y2);
          x1^=ans,x2^=ans,y1^=ans,y2^=ans;
          ans=0;
          kd.query(rt,x1,x2,y1,y2);
          cout<<ans<<endl;
        }
      }
      
      return 0; 
    }
  • 相关阅读:
    Minimum Depth of Binary Tree leetcode java
    Maximum Depth of Binary Tree leetcode java
    Symmetric Tree leetcode java
    Same Tree leetcode java
    Binary Tree Postorder Traversal leetcode java
    Binary Tree Preorder Traversal leetcode java
    Binary Tree Inorder Traversal leetcode java
    Combinations leetcode java
    一键清除Centos iptables 防火墙所有规则
    阿里云centos7.7x64安装open,并配置ip转发和nat伪装
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9288414.html
Copyright © 2011-2022 走看看