zoukankan      html  css  js  c++  java
  • 2017 3 17 线段树套主席树

        写了半场考试你告我正解是bitset??而且竟然比我跑得快??

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<vector>
      6 #define inf 0x3f3f3f3f
      7 #define N 50005
      8 #define ls a[x].l,a[y].l,l,mid
      9 #define rs a[x].r,a[y].r,mid+1,r
     10 using namespace std;
     11 int n;
     12 const int mx=50000;
     13 inline int read()
     14 {
     15     char c=getchar();int p=0,f=1;
     16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     17     while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();
     18     return p*f;
     19 }
     20 struct fk
     21 {
     22     struct point
     23     {
     24         int x,y;
     25         friend bool operator < (const point &aa,const point &bb)
     26         {
     27             if(aa.y!=bb.y)return aa.y<bb.y;
     28             return aa.x<bb.x;
     29         }
     30     }dian[N];
     31     int lix[N+5],liy[N+5],cnt1,cnt2,pre[mx+5],now[mx+5];
     32     struct node
     33     {
     34         int l,r,sum;
     35     }a[N*350];int cnt;
     36     int qur(int x,int y,int l,int r,int ll,int rr)
     37     {
     38         if(l>=ll&&r<=rr)return a[x].sum-a[y].sum;
     39         int mid=(l+r)>>1;
     40         if(ll>mid)return qur(rs,ll,rr);
     41         if(rr<=mid)return qur(ls,ll,rr);
     42         return qur(ls,ll,rr)+qur(rs,ll,rr);
     43     }
     44     void insert(int x,int y,int l,int r,int pos)
     45     {
     46         if(l==r)
     47         {
     48             a[x].sum=a[y].sum+1;
     49             return ;
     50         }
     51         int mid=(l+r)>>1;
     52         if(pos<=mid)
     53         {
     54             if(!a[x].l)a[x].l=++cnt;
     55             a[x].r=a[y].r;
     56             insert(ls,pos);
     57         }
     58         else 
     59         {
     60             if(!a[x].r)a[x].r=++cnt;
     61             a[x].l=a[y].l;
     62             insert(rs,pos);
     63         }
     64         a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
     65         return ;
     66     }
     67     vector<int>root[N*3],xx[N*3];
     68     vector<int>::iterator it;
     69     struct nd
     70     {
     71         int pr,yuan;
     72         nd(int x,int y)
     73         {
     74             yuan=x;pr=y;
     75         }
     76         friend bool operator < (const nd &aa,const nd &bb)
     77         {
     78             return aa.pr<bb.pr;
     79         }
     80     };
     81     vector<nd>pai[N*3];
     82     void jia(int x)
     83     {
     84         int pr=-1,prroot=0;
     85         root[x].push_back(0);xx[x].push_back(-1);
     86         for(int i=0;i<pai[x].size();i++)
     87         {
     88             int pp=pai[x][i].yuan;
     89             if(pre[pp]==pr)
     90             {
     91                 root[x][root[x].size()-1]=++cnt;
     92                 insert(root[x][root[x].size()-1],prroot,0,mx,dian[pp].x);
     93             }
     94             else
     95             {
     96                 root[x].push_back(++cnt);
     97                 xx[x].push_back(pre[pp]);
     98                 insert(root[x][root[x].size()-1],prroot,0,mx,dian[pp].x);
     99             }
    100             pr=pre[pp];
    101             prroot=root[x][root[x].size()-1];
    102         }
    103         xx[x].push_back(0x3f3f3f3f);
    104         return ;
    105     }
    106     void build(int x,int l,int r,int ll,int rr)
    107     {
    108         if(ll>rr)return ;
    109         int mid=(l+r)>>1;
    110         int ed=rr;
    111         for(int i=ll;i<=rr;i++)
    112         {
    113             if(dian[i].y<=mid)ed=i;
    114             pai[x].push_back(nd(i,pre[i]));
    115         }
    116         sort(pai[x].begin(),pai[x].end());
    117         jia(x);
    118         if(l==r)return ;
    119         build(x*2,l,mid,ll,ed);
    120         build(x*2+1,mid+1,r,ed+1,rr);
    121     }
    122     int qu(int x,int l,int r,int ll,int rr,int qx,int qy)
    123     {
    124         if(ll<=l&&rr>=r)
    125         {
    126             int ha=0;int ta=xx[x].size()-1;
    127             while(ha<=ta)
    128             {
    129                 int mid=(ha+ta)>>1;
    130                 if(xx[x][mid]<ll)ha=mid+1;
    131                 else ta=mid-1;
    132             }
    133             return qur(root[x][ta],0,0,mx,qx,qy);
    134         }
    135         int mid=(l+r)>>1;
    136         if(ll>mid)return qu(x*2+1,mid+1,r,ll,rr,qx,qy);
    137         if(rr<=mid)return qu(x*2,l,mid,ll,rr,qx,qy);
    138         return qu(x*2+1,mid+1,r,ll,rr,qx,qy)+qu(x*2,l,mid,ll,rr,qx,qy);
    139     }
    140     int que(int x1,int y1,int x2,int y2)
    141     {
    142         if(y1>liy[cnt2]||x1>lix[cnt1])return 0;
    143         if(y2<liy[1]||x2<lix[1])return 0;
    144         y1=lower_bound(liy+1,liy+cnt2+1,y1)-liy;
    145         x1=lower_bound(lix+1,lix+cnt1+1,x1)-lix;
    146         if(y2<liy[cnt2])y2=upper_bound(liy+1,liy+cnt2+1,y2)-liy-1;else y2=cnt2;
    147         if(x2<lix[cnt1])x2=upper_bound(lix+1,lix+cnt1+1,x2)-lix-1;else x2=cnt1;
    148         return qu(1,1,mx,y1,y2,x1,x2);
    149     }
    150     void srt()
    151     {
    152         sort(dian+1,dian+n+1);
    153         for(int i=1;i<=n;i++)
    154         {
    155             lix[++cnt1]=dian[i].x;
    156             liy[++cnt2]=dian[i].y;
    157         }
    158         sort(lix+1,lix+cnt1+1);sort(liy+1,liy+cnt2+1);
    159         cnt1=unique(lix+1,lix+cnt1+1)-lix-1;
    160         cnt2=unique(liy+1,liy+cnt2+1)-liy-1;
    161         for(int i=1;i<=n;i++)
    162         {
    163             dian[i].x=lower_bound(lix+1,lix+cnt1+1,dian[i].x)-lix;
    164             dian[i].y=lower_bound(liy+1,liy+cnt2+1,dian[i].y)-liy;
    165         }
    166         return ;
    167     }
    168     void yu()
    169     {
    170         for(int i=1;i<=n;i++)
    171         {
    172             pre[i]=now[dian[i].x];
    173             now[dian[i].x]=dian[i].y;
    174         }
    175     }
    176 }sx,sy;
    177 int on,t1,t2,t3,t4,t5;
    178 int main()
    179 {
    180     scanf("%d",&on);
    181     scanf("%d",&n);
    182     for(int i=1;i<=n;i++)
    183     {
    184         t1=read();t2=read();
    185         sy.dian[i].x=t1;sy.dian[i].y=t2;
    186         sx.dian[i].x=t2;sx.dian[i].y=t1;
    187     }
    188     sx.srt();
    189     sy.srt();
    190     sx.yu();
    191     sy.yu();
    192     sx.build(1,1,mx,1,n);
    193     sy.build(1,1,mx,1,n);
    194     int cas;
    195     scanf("%d",&cas);int lax=0,lay=0;
    196     while(cas--)
    197     {
    198         t1=read();t2=read();t3=read();t4=read();
    199         t1=t1+(lax+lay)*on;
    200         t2=t2+(lax+lay)*on;
    201         t3=t3+(lax+lay)*on;
    202         t4=t4+(lax+lay)*on;
    203         lay=sx.que(t2,t1,t4,t3);
    204         lax=sy.que(t1,t2,t3,t4);
    205         printf("%d %d
    ",lax,lay);
    206     }
    207     return 0;
    208 }
  • 相关阅读:
    《挑战30天C++入门极限》新手入门:关于C++中的内联函数(inline)
    《挑战30天C++入门极限》新手入门:C/C++中枚举类型(enum)
    《挑战30天C++入门极限》新手入门:C++中布尔类型
    《挑战30天C++入门极限》新手入门:C++下的引用类型
    《挑战30天C++入门极限》新手入门:C/C++中数组和指针类型的关系

    《挑战30天C++入门极限》入门教程:C++中的const限定修饰符
    《挑战30天C++入门极限》c++中指针学习的两个绝好例子
    《挑战30天C++入门极限》在c/c++中利用数组名作为函数参数传递排序和用指针进行排序的例子。
    《挑战30天C++入门极限》引言
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6567893.html
Copyright © 2011-2022 走看看