ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】~~文体~~陌上花开

2019-03-07 17:02:00  阅读:235  来源: 互联网

标签:文体 edd 题解 分治 陌上 cdq 有序 define


【题解】文体陌上花开

像全国人民谢罪了

陌上花开可缓缓归矣

\(cdq\)做的,待会发\(kd-tree\)

多维偏序如何做的本质是按照时间分治,时间在前面的对时间在后面的有影响,所以可以用树状数组统计答案。

和其他分治差不多,就是保证一维有序,从而为我们从中间分开分治提供可能。这类分治的一个基本原则就是尽量保证一定范围的有序以让我便于统计答案。因为有序为我们设计算法提供太多的可能!

解释一下我是什么意思,我对局部有序的理解就是可以保证一个范围\(S\)中的所有元素会比另一个范围\(C_US\)的任意元素都要小。这样就可以在第二维上进行排序,开花,这样我们保证小范围内的第二维有序之后,我们就可以基于时间对第三维设计算法了。

但是\(cdq​\)有个致命的地方,无法处理两个元素完全相等这种情况,我们可以使用类似离散化的思想,把所有相同的元素合并在一起。统计答案的时候另外设计算法。

待会加\(kd-tree​\)的

\(cdq\)一遍写过的我非常自豪,而且没看题解QAQ!!(你tm拿暴力拍了10000组还要怎么样)

现在我要向又短又快的代码看齐

#include<bits/stdc++.h>

using namespace std;typedef long long ll;
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define RP(t,a,b)  for(register int t=(a),edd=(b);t<=edd;++t)
#define ERP(t,a)   for(register int t=head[a];t;t=e[t].nx)
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lef l,mid
#define rgt mid+1,r
#define lb(x) ((x)&(-(x)))
#define pushup(pos) (seg[pos]=seg[pos<<1]+seg[pos<<1|1])
TMP inline ccf qr(ccf b){
    register char c=getchar();register int q=1;register ccf x=0;
    while(c<48||c>57)q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
    return q==-1?-x:x;}
TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
TMP inline ccf Max(ccf a,ccf b,ccf c){return Max(a,Max(b,c));}
TMP inline ccf Min(ccf a,ccf b,ccf c){return Min(a,Min(b,c));}
TMP inline ccf READ(ccf* _arr,int _n){RP(t,1,_n)_arr[t]=qr((ccf)1);}
//----------------------template&IO---------------------------
const int maxn=1e5+15;
int seg[maxn<<1];
int buk[maxn];
struct NODE{
    int x,y,z,T,ape;
    inline bool operator < (NODE a)const{return x==a.x?(y==a.y?(z<a.z):(y<a.y)):(x<a.x);}
    inline bool operator ==(NODE a)const{return x==a.x and y==a.y and z==a.z;}
    inline void scan(){x=qr(1)+1;y=qr(1)+1;z=qr(1)+1;T=1;}
}oj[maxn],data[maxn],temp[maxn];
// move right 1 unit
int n,k,sz;
int ans[maxn];
int q1[maxn],q2[maxn],cnt;


inline void add(int now,int v){
    ++cnt;q1[cnt]=now;q2[cnt]=v;
    for(register int t=now;t<=k;t+=lb(t)) seg[t]+=v;
}
inline void rec(){
    RP(t,1,cnt) add(q1[t],-q2[t]);
    cnt=0;
}
inline int que(int now){
    register int ret=0;
    for(register int t=now;t;t-=lb(t)) ret+=seg[t];
    return ret;
}

void cdq(int l,int r){midd;
    if(l==r){data[l].ape+=data[l].T-1;return;}
    cdq(lef);cdq(rgt);
    register int L=l,R=mid+1,K=l;
    while(L<=mid&&R<=r){
    if(data[L].y<=data[R].y){
        add(data[L].z,data[L].T);temp[K++]=data[L++];
    }
        else{
        data[R].ape+=que(data[R].z);temp[K++]=data[R++];
    }
    }
    while(L<=mid) add(data[L].z,data[L].T),temp[K++]=data[L++];
    while(R<=r) data[R].ape+=que(data[R].z),temp[K++]=data[R++];
    RP(t,l,r) data[t]=temp[t];
    rec();
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    n=qr(1);k=qr(1)+1;
    RP(t,1,n) oj[t].scan();
    sort(oj+1,oj+n+1);
    for(register int t=1;t<=n;  ){
    data[++sz]=oj[t++];
    while(t<=n&&oj[t]==data[sz]) ++t,++data[sz].T;
    }
    cdq(1,sz);
    RP(t,1,sz) buk[data[t].ape]+=data[t].T;
    RP(t,0,n-1) printf("%d\n",buk[t]);
    return 0;
}

标签:文体,edd,题解,分治,陌上,cdq,有序,define
来源: https://www.cnblogs.com/winlere/p/10490695.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有