【bzoj 3262】: 陌上花开

来源:互联网 发布:大数据 徐子沛pdf 编辑:程序博客网 时间:2024/06/10 16:37


http://www.lydsy.com/JudgeOnline/problem.php?id=3262



有人说有O(nlogn)的不sort的方法,简直是胡扯。。。
中间还不是O(nlogn)的BIT。。。
一样的T(n)=2T(n/2)+O(nlogn)自己算算、、、


一定要先去重么。。。?


jcvb:
关键在于等号的处理。按a排序,并把a值相同的三元组放到一个段内。CDQ分治时以段为最小单位,这样每次将序列分成两部分时,可以保证左半部分的a都严格 小于右半部分的a,于是我们可以统计a'<a,b'<=b,c'<=c的数量。可以证明这样的复杂度仍然是O(nlog^2n)。
再统计每一段内,a'==a,b'<=b,c'<=c的数量。


我的方法和这个差不多,因为如果有了重复,那么重复的之间是可能不会计算的(比如分在同一块)

也就是保证右边不能对左边不能有贡献。。。


#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <cmath>#include <algorithm>using namespace std;#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)#define MS(arr,x) memset(arr,x,sizeof(arr))#define INE(i,u) for(int i=head[u];~i;i=e[i].next)#define LL long longinline const int read(){int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}////////////////////////////////////////////////const int N=100010;int n,k;struct data{int x,y,z,s,ans;}a[N],c[N];int tot;int ans[N];int b[2*N];////////////////////////////////////////////////inline bool cmp(const data &A,const data &B){if(A.x!=B.x) return A.x<B.x;if(A.y!=B.y) return A.y<B.y;return A.z<B.z;}inline bool cmp2(const data &A,const data &B){if(A.y!=B.y) return A.y<B.y;return A.z<B.z;}void add(int o,int x){for(;o<=k;o+=o&-o)b[o]+=x;}int query(int o){int s=0;for(;o;o-=o&-o)s+=b[o];return s;}void cdq(int l,int r){if(l==r) return;int mid=l+r>>1;cdq(l,mid); cdq(mid+1,r);int i=l,j=mid+1;for(;j<=r;j++){for(;i<=mid && c[i].y <= c[j].y;i++){add(c[i].z,c[i].s);}c[j].ans+=query(c[j].z);}rep(j,l,i-1) add(c[j].z,-c[j].s); // 清空,妈呀是i-1不是mid,该死! sort(&c[l],&c[r+1],cmp2);}////////////////////////////////////////////////void input(){    n=read(); k=read();    rep(i,1,n) a[i].x=read(), a[i].y=read(), a[i].z=read();    sort(&a[1],&a[n+1],cmp);}void solve(){int cnt=0;rep(i,1,n){cnt++;if(memcmp(&a[i],&a[i+1],sizeof(a[i])))    memcpy(&c[++tot],&a[i],sizeof(a[i])),c[tot].s=cnt,cnt=0;}cdq(1,tot);rep(i,1,tot) ans[c[i].ans+c[i].s-1]+=c[i].s;rep(i,0,n-1) printf("%d\n",ans[i]);}////////////////////////////////////////////////int main(){    //freopen("_.in","r",stdin); freopen("_.out","w",stdout);    input(),solve();    return 0;}


0 0
原创粉丝点击