BOI2007 Mokia
阿新 • • 發佈:2018-12-08
這個題其實和板子題差不多……不過這次修改和詢問是分離開的,然後一個詢問要被拆分成4個,就是維護二維字首和的方式。
我的做法比較奇怪……(怎麼我\(CDQ\)分治的題做法都很奇怪),別人都是按時間排序然後歸併x,樹狀陣列統計y,用x作為限制,因為這樣時間天然有序。我是按x排序然後歸併時間……其實這樣也能做,但是一來比較慢(一開始要\(sort\)),二來我非常智障的把每個詢問的時間沒有搞成同一個值……
之後套板子做就可以了。
// luogu-judger-enable-o2 #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<vector> #include<map> #include<queue> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n') #define fr friend inline #define y1 poj #define mp make_pair #define pr pair<int,int> #define fi first #define sc second #define pb push_back #define lowbit(x) x & (-x) #define B printf("Bug\n"); using namespace std; typedef long long ll; const int M = 400005; const int N = 2000005; const double INF = 1e15; const double eps = 1e-7; int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } struct node { int x,y,tim,val; bool opa; bool operator < (const node &g)const { if(x == g.x && tim == g.tim) return y < g.y; if(x == g.x) return tim < g.tim; return x < g.x; } }a[M]; int n,cnt,x1,y1,x2,y2,A,op,ans[N],Ti; bool vis[N]; struct treearray { int c[N]; void add(int x,int v) {while(x <= N-2) c[x] += v,x += lowbit(x);} int ask(int x) {int cur = 0;while(x) cur += c[x],x -= lowbit(x); return cur;} }T; bool cmp(const node &p,const node &q) { if(p.tim == q.tim) return p.y < q.y; return p.tim < q.tim; } void CDQ(const int &l,const int &r) { if(l == r) return; int mid = (l+r) >> 1; CDQ(l,mid),CDQ(mid+1,r); sort(a+l,a+mid+1,cmp),sort(a+mid+1,a+r+1,cmp); int j = l; rep(i,mid+1,r) { if(a[i].opa) continue; while(j <= mid && a[j].tim < a[i].tim) { if(!a[j].opa) {j++;continue;} T.add(a[j].y,a[j].val),j++; } ans[a[i].tim] += a[i].val * T.ask(a[i].y); } rep(i,l,j-1) if(a[i].opa) T.add(a[i].y,-a[i].val); } int main() { n = read(),n = read(); while(scanf("%d",&op) && op != 3) { Ti++; if(op == 1) a[++cnt].x = read(),a[cnt].y = read(),a[cnt].val = read(),a[cnt].opa = 1,a[cnt].tim = Ti; else { x1 = read(),y1 = read(),x2 = read(),y2 = read(),vis[Ti] = 1; a[++cnt].x = x1-1,a[cnt].y = y1-1,a[cnt].val = 1,a[cnt].tim = Ti; a[++cnt].x = x1-1,a[cnt].y = y2,a[cnt].val = -1,a[cnt].tim = Ti; a[++cnt].x = x2,a[cnt].y = y1-1,a[cnt].val = -1,a[cnt].tim = Ti; a[++cnt].x = x2,a[cnt].y = y2,a[cnt].val = 1,a[cnt].tim = Ti; } } sort(a+1,a+1+cnt); CDQ(1,cnt); rep(i,1,Ti) if(vis[i]) printf("%d\n",ans[i]); return 0; }