HDU 6183 Color it(cdq分治)

xiaoxiao2021-02-28  89

题目链接:

三维偏序问题,直接cdq+线段树就可以做了,比较裸。。。

代码:

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=150000+5; const int M=1e6+5; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void rea(int &x) { char c=nc();x=0; for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); } struct node { int op,x,y,c,id; node(){} node(int _op,int _x,int _y,int _c,int _id):op(_op),x(_x),y(_y),c(_c),id(_id){} }sv[MAXN]; struct seg { #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 ll sum[M<<2]; void update(int pos,ll val,int l,int r,int rt,bool del) { if(l==r) { if(del) { if(sum[rt]&val) sum[rt]^=val; } else sum[rt]|=val; return ; } int mid=(l+r)>>1; if(mid>=pos) update(pos,val,lson,del); if(mid<pos) update(pos,val,rson,del); sum[rt]=(sum[rt<<1]|sum[rt<<1|1]); } ll query(int L,int R,int l,int r,int rt) { if(L>R) return 0; if(L<=l&&r<=R) return sum[rt]; int mid=(l+r)>>1; ll ret=0; if(mid>=L) ret|=query(L,R,lson); if(mid<R) ret|=query(L,R,rson); return ret; } }T; int n; ll ans[MAXN]; bool cmpid(const node &a,const node &b) { return a.id<b.id; } bool cmpx(const node &a,const node &b) { if(a.x==b.x) return a.op<b.op; return a.x<b.x; } void cdq(int l,int r) { if(l==r) return ; int mid=(l+r)>>1; //printf("%lld\n",T.sum[1]); sort(sv+l,sv+r+1,cmpx); for(int i=l;i<=r;i++) { if(sv[i].id<=mid) { if(sv[i].op==1) { T.update(sv[i].y,(1LL<<sv[i].c),1,1000000,1,false); } } else { if(sv[i].op==2) { ans[sv[i].id]|=T.query(sv[i].y,sv[i].c,1,1000000,1); } } } for(int i=l;i<=r;i++) { if(sv[i].id<=mid) { if(sv[i].op==1) { T.update(sv[i].y,(1LL<<sv[i].c),1,1000000,1,true); } } } sort(sv+l,sv+r+1,cmpid); cdq(l,mid);cdq(mid+1,r); } void init() { n=0; memset(ans,0,sizeof(ans)); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); rea(n); while(1) { int op,x,y,c; init(); while(1) { rea(op); if(op==0||op==3) { break; } rea(x);rea(y);rea(c); sv[++n]=node(op,x,y,c,n); } cdq(1,n); for(int i=1;i<=n;i++) { if(sv[i].op==2)\ printf("%d\n",__builtin_popcountll(ans[i])); } if(op==3) break; } return 0; }

转载请注明原文地址: https://www.6miu.com/read-41229.html

最新回复(0)