[luogu3810][bzoj3262][陌上花開]
阿新 • • 發佈:2018-12-11
題目連結
思路
聽說可以CDQ分治,然後我不會,所以我寫樹套樹
首先肯定先按照a拍個序。然後就成了在b,c這兩個陣列中查詢了。用一個樹狀陣列套treap來維護。當插入一個數的時候,就在樹狀陣列的b這個位置的treap里加入一個c。然後查詢的時候就直接把小於等於c的數的個數進行字首和就行了。
注意題目裡面是小於等於。所以在按照a加入的時候,要把a相同的數一起加進去。
程式碼
/* * @Author: wxyww * @Date: 2018-12-11 14:01:32 * @Last Modified time: 2018-12-11 14:28:01 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<ctime> #include<bitset> #include<map> #include<algorithm> using namespace std; typedef long long ll; const int N = 100000 + 100,M = 200000 + 100; #define ls TR[cur].ch[0] #define rs TR[cur].ch[1] ll read() { ll x=0,f=1;char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } struct node { int a,b,c; }e[N]; bool operator < (const node &x,const node &y) { return x.a < y.a; } int rt[N]; int tot = 0; namespace treap { struct NODE { int ch[2],id,val,siz,cnt; }TR[M * 30]; void up(int cur) { TR[cur].siz = TR[ls].siz + TR[rs].siz + TR[cur].cnt; } void rotate(int &cur,int f) { int son = TR[cur].ch[f]; TR[cur].ch[f] = TR[son].ch[f ^ 1]; TR[son].ch[f ^ 1] = cur; up(cur);cur = son;up(cur); } void insert(int &cur,int val) { if(!cur) { cur = ++tot; TR[cur].val = val; TR[cur].cnt = TR[cur].siz = 1; TR[cur].id = rand(); return; } TR[cur].siz++; if(TR[cur].val == val) {TR[cur].cnt++;return;} int d = val > TR[cur].val; insert(TR[cur].ch[d],val); if(TR[TR[cur].ch[d]].id < TR[cur].id) rotate(cur,d); } int Rank(int cur,int val) { int ans = 0; while(cur) { if(val == TR[cur].val) return ans + TR[ls].siz + TR[cur].cnt; if(val > TR[cur].val) ans += TR[ls].siz + TR[cur].cnt,cur = rs; else cur = ls; } return ans; } } using namespace treap; int tree[M],K; void add(int pos,int c) { while(pos <= K) { insert(tree[pos],c); pos += pos & -pos; } } int query(int pos,int x) { int ans = 0; while(pos >= 1) { ans += Rank(tree[pos],x); pos -= pos & -pos; } return ans; } int have_ad[N]; int ans[N]; int main() { int n = read();K = read(); for(int i = 1;i <= n;++i) e[i].a = read(),e[i].b = read(),e[i].c = read(); sort(e + 1,e + n + 1); for(int i = 1;i <= n;++i) { if(!have_ad[i]) add(e[i].b,e[i].c); int js = 1; while(e[i + js].a == e[i].a && !have_ad[i]) { have_ad[i + js] = 1; add(e[i + js].b,e[i + js].c); js++; } have_ad[i] = 1; ans[query(e[i].b,e[i].c)]++; } for(int i = 1;i <= n;++i) printf("%d\n",ans[i]); return 0; }