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; 
    }
  • 相关阅读:
    ZeroMQ接口函数之 :zmq_z85_decode – 从一个用Z85算法生成的文本中解析出二进制密码
    ZeroMQ接口函数之 :zmq_init
    ZeroMQ接口函数之 :zmq_errno – 返回errno的值给调用此函数的线程
    ZeroMQ接口函数之 :zmq_disconnect
    ZeroMQ接口函数之 :zmq_curve_keypair
    ZeroMQ接口函数之 :zmq_curve – 安全的认证方式和保密方式
    ZeroMQ接口函数之 :zmq_ctx_term
    ZeroMQ接口函数之 :zmq_socket_monitor
    ZeroMQ接口函数之 :zmq_ctx_shutdown
    ZeroMQ接口函数之 :zmq_ctx_set
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9288414.html
Copyright © 2011-2022 走看看