zoukankan      html  css  js  c++  java
  • hdu5126stars

    http://acm.hdu.edu.cn/showproblem.php?pid=5126

    首先,对于一个询问,用容斥原理可以拆成8个询问,于是询问变成:给定一个四元组$(i,x_i,y_i,z_i)$,问满足$j<i$,$x_jleq x_i$,$y_j leq y_i$,$z_j leq z_i$的四元组$(j,x_j,y_j,z_j)$有多少个。

    四维偏序。。。。。。。。。。。

    用CDQ分治套CDQ分治,把四维偏序降为三维偏序。

    CDQ大法好。

    //http://acm.hdu.edu.cn/showproblem.php?pid=5126
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define fill(a,l,r,v) fill(a+l,a+r+1,v)
    #define re(i,a,b)  for(i=(a);i<=(b);i++)
    #define red(i,a,b) for(i=(a);i>=(b);i--)
    #define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define p_b(a) push_back(a)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    inline int sgn(DB x){if(abs(x)<1e-9)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxn=50000;
    
    int q,n;
    struct Tstar
      {
          int p,x,y,z,s;
          Tstar(int p=0,int x=0,int y=0,int z=0,int s=0):p(p),x(x),y(y),z(z),s(s){}
      };
    int res[8*maxn+100];
    
    bool cmpz(Tstar a,Tstar b){return a.z<b.z;}
    bool cmpp(Tstar a,Tstar b){return a.p<b.p;}
    
    int nz,tree[8*maxn+100];
    #define lowbit(a) ((a)&(-a))
    void update(int a,int v){for(;a<=nz;a+=lowbit(a))tree[a]+=v;}
    int ask(int a){int res=0;for(;a>=1;a-=lowbit(a))res+=tree[a];return res;}
    
    Tstar tmp[8*maxn+100];
    
    Tstar star2[8*maxn+100];
    void CDQ2(int l,int r)
      {
          if(l==r)return;
            int i,mid=(l+r)/2;
            CDQ2(l,mid);
            CDQ2(mid+1,r);
            int l1=l,l2=mid+1;
            while(1)
              {
                  while(l2<=r && star2[l2].s==0)l2++;
                  if(l2>r)break;
                  while(l1<=mid && star2[l1].y<=star2[l2].y)
                    {
                        if(star2[l1].s==0)update(star2[l1].z,1);
                        l1++;
                    }
                  res[star2[l2].p]+=ask(star2[l2].z);
                  l2++;
              }
            re(i,l,l1-1)if(star2[i].s==0)update(star2[i].z,-1);
            l1=l,l2=mid+1;
            re(i,l,r)
              {
                  if(l1>mid){tmp[i]=star2[l2++];continue;}
                  if(l2>r){tmp[i]=star2[l1++];continue;}
                  if(star2[l1].y<=star2[l2].y)tmp[i]=star2[l1++];else tmp[i]=star2[l2++];
              }
            re(i,l,r)star2[i]=tmp[i];
      }
    
    Tstar star[8*maxn+100];
    void CDQ1(int l,int r)
      {
          if(l==r)return;
          int i,mid=(l+r)/2;
          CDQ1(l,mid);
          CDQ1(mid+1,r);
          int l1=l,l2=mid+1,n=0;
          while(1)
            {
                while(l1<=mid && star[l1].s!=0)l1++;
                while(l2<=r && star[l2].s==0)l2++;
                if(l1>mid && l2>r)break;
                if(l1>mid){star2[++n]=star[l2++];continue;}
                if(l2>r){star2[++n]=star[l1++];continue;}
                if(star[l1].x<=star[l2].x)star2[++n]=star[l1++];else star2[++n]=star[l2++];
            }
            if(n>0)CDQ2(1,n);
            l1=l,l2=mid+1;
            re(i,l,r)
              {
                  if(l1>mid){tmp[i]=star[l2++];continue;}
                  if(l2>r){tmp[i]=star[l1++];continue;}
                  if(star[l1].x<=star[l2].x)tmp[i]=star[l1++];else tmp[i]=star[l2++];
              }
            re(i,l,r)star[i]=tmp[i];
      }
    
    int main()
      {
          freopen("hdu5126.in","r",stdin);
          freopen("hdu5126.out","w",stdout);
          for(int Case=gint();Case;Case--)
            {
                int i,j;
                q=gint();n=0;
                re(i,1,q)
                  {
                      int A=gint();
                      if(A==1)
                        {
                            int x=gint(),y=gint(),z=gint();
                            star[++n]=Tstar(n,x,y,z,0);
                        }
                      else
                        {
                            int x1=gint(),y1=gint(),z1=gint(),x2=gint(),y2=gint(),z2=gint();
                            star[++n]=Tstar(n,x2  ,y2  ,z2  ,1 );
                            star[++n]=Tstar(n,x2  ,y2  ,z1-1,-1);
                            star[++n]=Tstar(n,x2  ,y1-1,z2  ,-1);
                            star[++n]=Tstar(n,x2  ,y1-1,z1-1,1 );
                            star[++n]=Tstar(n,x1-1,y2  ,z2  ,-1);
                            star[++n]=Tstar(n,x1-1,y2  ,z1-1,1 );
                            star[++n]=Tstar(n,x1-1,y1-1,z2  ,1 );
                            star[++n]=Tstar(n,x1-1,y1-1,z1-1,-1);
                        }
                  }
                sort(star+1,star+n+1,cmpz);
                nz=0;
                int tmpz=-100;
                re(i,1,n)if(star[i].z==tmpz)star[i].z=nz;else tmpz=star[i].z,star[i].z=++nz;
                sort(star+1,star+n+1,cmpp);
                    re(i,1,n)res[i]=0;
                CDQ1(1,n);
                sort(star+1,star+n+1,cmpp);
                re(i,1,n)
                  if(star[i].s!=0)
                    {
                        int ans=0;
                        re(j,0,7)ans+=star[i+j].s*res[i+j];
                        PF("%d
    ",ans);
                        i+=7;
                    }
            }
          return 0;
      }
    View Code
  • 相关阅读:
    2016.10.15先占坑
    2016.10.11先占坑
    2016.10.13先占坑
    2016.10.7先占坑
    main()里面为什么要放String[] args
    对于一个给定的正整数 n ,请你找出一共有多少种方式使 n 表示为若干个连续正整数的和,要求至少包括两个正整数。
    求两个数的最大公约数的三种算法总结
    C++
    Dev-c5.11的使用
    客户端和服务器端的交互(未完待续)
  • 原文地址:https://www.cnblogs.com/maijing/p/4857785.html
Copyright © 2011-2022 走看看