cdq分治
1.二维星星点灯
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<cstring> 6 #include<ctime> 7 #include<iomanip> 8 #include<queue> 9 #include<map> 10 #include<set> 11 #include<algorithm> 12 using namespace std; 13 #define FILE "dealing" 14 #define LL long long 15 #define up(i,j,n) for(int i=(j);i<=(n);i++) 16 #define re(i,j,n) for(int i=(j);i<(n);i++) 17 void chkmin(int &a,int b){a>b?a=b:0;} 18 void chkmax(int &a,int b){a<b?a=b:0;} 19 namespace IO{ 20 char buf[1<<15],*fs,*ft; 21 int gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} 22 int read(){ 23 int x=0,f=0,ch=gc(); 24 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();} 25 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} 26 return f?-x:x; 27 } 28 }using namespace IO; 29 const int maxn=202000; 30 int n; 31 int x[maxn],y[maxn],ans[maxn]; 32 struct node{ 33 int x,y,ans,id; 34 bool operator<(const node& b)const{return x<b.x||(x==b.x&&y<b.y);} 35 void mem(){x=y=ans=0;} 36 }a[maxn],c[maxn]; 37 void dfs(int l,int r){ 38 if(l==r||l>r)return; 39 int mid=(l+r)>>1; 40 dfs(l,mid); 41 dfs(mid+1,r); 42 up(i,l,r)c[i].mem(); 43 int x=l,y=mid+1; 44 for(int i=l;i<=r;i++){ 45 if(x<=mid&&y<=r){ 46 if(a[x].y<=a[y].y)c[i]=a[x++]; 47 else a[y].ans+=x-l,c[i]=a[y++]; 48 continue; 49 } 50 if(x<=mid)c[i]=a[x++]; 51 if(y<=r)a[y].ans+=x-l,c[i]=a[y++]; 52 } 53 for(int i=l;i<=r;i++)a[i]=c[i]; 54 } 55 bool cmp(node a,node b){return a.id<b.id;} 56 int main(){ 57 freopen(FILE".in","r",stdin); 58 freopen(FILE".out","w",stdout); 59 n=read(); 60 up(i,1,n)a[i].x=read(),a[i].y=read(),a[i].id=i; 61 sort(a+1,a+n+1); 62 dfs(1,n); 63 sort(a+1,a+n+1,cmp); 64 up(i,1,n)printf("%d\n",a[i].ans); 65 return 0; 66 }
2.baoj3262三维星星点灯
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<cstring> 6 #include<ctime> 7 #include<iomanip> 8 #include<queue> 9 #include<map> 10 #include<set> 11 #include<algorithm> 12 using namespace std; 13 #define FILE "dealing" 14 #define LL long long 15 #define up(i,j,n) for(int i=(j);i<=(n);i++) 16 #define re(i,j,n) for(int i=(j);i<(n);i++) 17 void chkmin(int &a,int b){a>b?a=b:0;} 18 void chkmax(int &a,int b){a<b?a=b:0;} 19 namespace IO{ 20 char buf[1<<15],*fs,*ft; 21 int gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} 22 int read(){ 23 int x=0,f=0,ch=gc(); 24 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();} 25 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} 26 return f?-x:x; 27 } 28 }using namespace IO; 29 const int maxn=202000; 30 int n,K,top=0; 31 struct node{ 32 int x,y,z,ans,c; 33 bool operator<(const node& b)const{return x<b.x||(x==b.x&&y<b.y)||(x==b.x&&y==b.y&&z<b.z);} 34 void mem(){x=y=ans=0;} 35 }a[maxn],c[maxn]; 36 int b[maxn]; 37 int lowbit(int x){return x&-x;} 38 void add(int x,int d){while(x<=K)b[x]+=d,x+=lowbit(x);} 39 int getsum(int x){int ans=0;while(x)ans+=b[x],x-=lowbit(x);return ans;} 40 bool cmp(node a,node b){return a.y<b.y||(a.y==b.y&&a.z<b.z);} 41 void dfs(int l,int r){ 42 if(l==r||l>r)return; 43 int mid=(l+r)>>1; 44 dfs(l,mid);dfs(mid+1,r); 45 int x=l,y=mid+1; 46 for(int i=l;i<=r;i++){ 47 if(x<=mid&&y<=r){ 48 if(a[x].y<=a[y].y)add(a[x].z,a[x].c),c[i]=a[x++]; 49 else a[y].ans+=getsum(a[y].z),c[i]=a[y++]; 50 continue; 51 } 52 if(x<=mid)add(a[x].z,a[x].c),c[i]=a[x++]; 53 if(y<=r)a[y].ans+=getsum(a[y].z),c[i]=a[y++]; 54 } 55 up(i,l,mid)add(a[i].z,-a[i].c); 56 up(i,l,r)a[i]=c[i]; 57 return; 58 } 59 int h[maxn]; 60 int main(){ 61 freopen(FILE".in","r",stdin); 62 freopen(FILE".out","w",stdout); 63 n=read(),K=read(); 64 up(i,1,n)a[i].x=read(),a[i].y=read(),a[i].z=read(),a[i].c=1; 65 sort(a+1,a+n+1); 66 up(i,1,n){ 67 if(i==1||a[i-1]<a[i])a[++top]=a[i]; 68 else a[top].c++; 69 } 70 swap(top,n); 71 dfs(1,n); 72 up(i,1,n)h[a[i].ans+a[i].c]+=a[i].c; 73 up(i,1,top)printf("%d\n",h[i]); 74 return 0; 75 }
这道题需要注意有三维都相同的点,需要缩点;
cdq分治的比较突出的能力是降维(x维,y维,z维,时间维等),使我们专注于当前需要解决的问题,代价是时间复杂度增加一个log;高端的暴力;