BZOJ 1176/2683 Mokia (三维偏序CDQ+树状数组)

题目大意:

洛谷传送门

三维偏序裸题。。

每次操作都看成一个三元组$<x,y,t>$,表示$x,y$坐标和操作时间$t $

询问操作拆成$4$个容斥

接下来就是$CDQ$了,外层按t排序,回溯时按$x$排序,用树状数组处理$y$这一维即可

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N1 201000
 6 #define M1 2001000
 7 #define ll long long
 8 #define dd double
 9 #define inf 0x3f3f3f3f3f3f3f3fll
10 using namespace std;
11 
12 int gint()
13 {
14     int ret=0,fh=1;char c=getchar();
15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
17     return ret*fh;
18 }
19 int n,m,ma;
20 struct BIT{
21 int s[M1];
22 void update(int x,int w){ for(int i=x;i<=ma;i+=(i&(-i))) s[i]+=w; }
23 int query(int x){ int ans=0; for(int i=x;i;i-=(i&(-i))) ans+=s[i]; return ans; }
24 void clr(int x){ for(int i=x;i<=ma;i+=(i&(-i))) s[i]=0;}
25 }s;
26 struct node{int x,y,w,t,ans,p;}a[N1],tmp[N1];
27 int cmp1(node s1,node s2){ if(s1.x!=s2.x) return s1.x<s2.x; return s1.y<s2.y; }
28 int cmp2(node s1,node s2){ if(s1.x!=s2.x) return s1.x<s2.x; return s1.y<=s2.y; }
29 int que[N1],tl;
30 
31 void CDQ(int L,int R)
32 {
33     if(R-L<=1) return;
34     int i,j,k,M=(L+R)>>1;
35     for(i=L,j=M,k=L;k<R;k++)
36     {
37         if(a[k].t<M) tmp[i++]=a[k];
38         else tmp[j++]=a[k];
39     }
40     for(k=L;k<R;k++) a[k]=tmp[k];
41     CDQ(L,M);
42     for(i=L,j=M;i<M&&j<R;)
43     {
44         if(cmp2(a[i],a[j])){ if(!a[i].p) { s.update(a[i].y,a[i].w); que[++tl]=i; } i++; }
45         else{ if(a[j].p) a[j].ans+=s.query(a[j].y); j++; }
46     }
47     while(i<M){ i++; }
48     while(j<R){ a[j].ans+=s.query(a[j].y); j++; }
49     while(tl){ s.clr(a[que[tl--]].y); }
50     CDQ(M,R);
51     for(i=L,j=M,k=0;i<M&&j<R;)
52     {
53         if(cmp2(a[i],a[j])) tmp[++k]=a[i++];
54         else tmp[++k]=a[j++];
55     }
56     while(i<M){ tmp[++k]=a[i++]; }
57     while(j<R){ tmp[++k]=a[j++]; }
58     for(k=L;k<R;k++) a[k]=tmp[k-L+1];
59 }
60 int f[N1];
61 
62 int main()
63 {
64     int i,op,xx1,xx2,yy1,yy2,w; op=gint(); ma=gint();
65     while(scanf("%d",&op)&&op!=3)
66     {
67         if(op==1) { n++; a[n].x=gint(); a[n].y=gint(); a[n].w=gint(); a[n].t=n;}
68         if(op==2)
69         {
70             xx1=gint(); yy1=gint(); xx2=gint(); yy2=gint(); m++;
71             n++; a[n].x=xx1-1; a[n].y=yy1-1; a[n].t=n; a[n].w=m; a[n].p=1;
72             n++; a[n].x=xx2; a[n].y=yy1-1; a[n].t=n; a[n].w=m; a[n].p=-1;
73             n++; a[n].x=xx1-1; a[n].y=yy2; a[n].t=n; a[n].w=m; a[n].p=-1;
74             n++; a[n].x=xx2; a[n].y=yy2; a[n].t=n; a[n].w=m; a[n].p=1;
75         }
76     }
77     sort(a+1,a+n+1,cmp1);
78     CDQ(1,n+1);
79     for(i=1;i<=n;i++) 
80     {
81         if(!a[i].w) continue;
82         f[a[i].w]+=a[i].p*a[i].ans;
83     }
84     for(i=1;i<=m;i++) printf("%d\n",f[i]);
85     return 0;
86 }

 

posted @ 2019-01-02 18:20  guapisolo  阅读(139)  评论(0编辑  收藏  举报