BOI2007 Mokia

分治套树状数组,板子题

 1 #include<bits/stdc++.h>
 2 #define FOR(i,a,b) for(int i=a,ie=b;i<=ie;++i)
 3 #define For(i,a,b) for(int i=a,ie=b;i<ie;++i)
 4 using namespace std;
 5 int read(){
 6     int x=0,f=1;char c=getchar();
 7     for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
 8     for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
 9     return x*f;
10 }
11 const int maxn=4e5+10;
12 typedef long long ll;
13 
14 int ans[maxn],a[maxn];
15 struct oper{
16     int x1,x2,y,f,id;//divide the y
17     oper(){};
18     oper(int x1,int x2,int y,int f,int id):
19         x1(x1),x2(x2),y(y),f(f),id(id){};
20 }q[maxn];
21 
22 bool cmp(oper a,oper b){
23     if(a.y!=b.y)return a.y<b.y;
24     return a.id<b.id;
25 }
26 
27 struct TAS{
28     int tr[maxn];
29     int lb(int x){return x&-x;}
30     void add(int x,int v){
31         for(;x<maxn;x+=lb(x))tr[x]+=v;
32     }
33     int sum(int x){
34         int ret=0;
35         for(;x>0;x-=lb(x))ret+=tr[x];
36         return ret;
37     }
38 }T;
39 
40 void solve(int l,int r){
41     if(l==r)return;
42     int mid=l+r>>1,j=0;
43     solve(l,mid);solve(mid+1,r);
44     vector<oper> s1,s2;
45     s1.clear(),s2.clear();
46     FOR(i,l,mid)if(!q[i].id)s1.push_back(q[i]);
47     FOR(i,mid+1,r)if(q[i].id)s2.push_back(q[i]);
48     sort(s1.begin(),s1.end(),cmp);
49     sort(s2.begin(),s2.end(),cmp);
50     For(i,0,s2.size()){
51         for(int je=s1.size();j<je;++j)
52             if(s1[j].y<=s2[i].y)
53                 T.add(s1[j].x1,s1[j].f);
54             else break;
55         ans[s2[i].id]+=s2[i].f*T.sum(s2[i].x2);
56         ans[s2[i].id]-=s2[i].f*T.sum(s2[i].x1-1);
57     }
58     For(i,0,j)T.add(s1[i].x1,-s1[i].f);
59 }
60 
61 int main(){
62     int op=read(),n=read(),m=0,id_cnt=0;
63     for(int x1,x2,y1,y2,v;(op=read())!=3;){
64         if(op&1){
65             x1=read();y1=read();v=read();
66             q[++m]=oper(x1,x1,y1,v,0);a[m]=x1;
67         }
68         else{
69             x1=read();y1=read();
70             x2=read();y2=read();
71             q[++m]=oper(x1,x2,y2,1,++id_cnt);a[m]=x2;
72             q[++m]=oper(x1,x2,y1-1,-1,id_cnt);a[m]=x1-1;
73         }
74     }
75     sort(a+1,a+m+1);
76     int cnt=unique(a+1,a+m+1)-(a+1);
77     for(int i=1;i<=m;++i){
78         if(!q[i].id)
79             q[i].x1=lower_bound(a+1,a+cnt+1,q[i].x1)-a;
80         else{
81             q[i].x1=lower_bound(a+1,a+cnt+1,q[i].x1-1)-a+1;
82             q[i].x2=lower_bound(a+1,a+cnt+1,q[i].x2)-a;
83         }
84     }
85     solve(1,m);
86     for(int i=1;i<=id_cnt;++i)printf("%d\n",ans[i]);
87     return 0;
88 }

 

posted @ 2019-08-13 15:04  人棍王楼下的AI  阅读(107)  评论(0编辑  收藏  举报