【BZOJ】【3262】陌上花开
树套树
orz zyf
这题的思路……算是让我了解到了树套树的一种用途吧
三维。。。第一维排序,第二维树状数组,第三维treap具体实现就是每个树状数组的节点保存一颗treap,然后就可以查询了。
好神啊……
树套树可以方便的进行特殊的区间求和,大多数满足区间加法的运算都可以用树套树来搞,比如这题的对所有第二维坐标小于当前点(相当于一段前缀)求第三维坐标小于当前点的和。= =啊……就是一个特殊的前缀和嘛……
还有就是这题其实有个K的……表示坐标的范围……所以树状数组要一直到k,而不是n
1 /************************************************************** 2 Problem: 3262 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:6728 ms 7 Memory:99128 kb 8 ****************************************************************/ 9 10 //BZOJ 3262 11 #include<cmath> 12 #include<vector> 13 #include<cstdio> 14 #include<cstring> 15 #include<cstdlib> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 #define pb push_back 22 #define CC(a,b) memset(a,b,sizeof(a)) 23 using namespace std; 24 int getint(){ 25 int v=0,sign=1; char ch=getchar(); 26 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 27 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 28 return v*sign; 29 } 30 const int N=210000,M=4000000,INF=~0u>>2; 31 const double eps=1e-8; 32 /*******************template********************/ 33 int n,k,tot,l[M],r[M],s[M],rnd[M],w[M],v[M]; 34 #define L l[x] 35 #define R r[x] 36 inline void Push_up(int x){ s[x]=s[L]+s[R]+w[x]; } 37 inline void zig(int &x){int t=L; L=r[t]; r[t]=x; s[t]=s[x]; Push_up(x); x=t;} 38 inline void zag(int &x){int t=R; R=l[t]; l[t]=x; s[t]=s[x]; Push_up(x); x=t;} 39 void ins(int &x,int num,int z){ 40 if (!x){ 41 x=++tot; v[x]=num; s[x]=w[x]=z; L=R=0; rnd[x]=rand(); return; 42 } 43 s[x]+=z; 44 if (v[x]==num) w[x]+=z; 45 else if(num<v[x]){ 46 ins(L,num,z); if(rnd[L]<rnd[x]) zig(x); 47 }else{ 48 ins(R,num,z); if(rnd[R]<rnd[x]) zag(x); 49 } 50 } 51 int rank(int x,int num){ 52 if (!x) return 0; 53 if (v[x]==num) return s[L]+w[x]; 54 else if(num<v[x]) return rank(L,num); 55 else return s[L]+w[x]+rank(R,num); 56 } 57 #undef L 58 #undef R 59 /*********************Treap*********************/ 60 int rt[N]; 61 void update(int x,int y,int z){ 62 for(int i=x;i<=k;i+=i&-i) ins(rt[i],y,z); 63 } 64 int query(int x,int y){ 65 int ans=0; 66 for(int i=x;i;i-=i&-i) ans+=rank(rt[i],y); 67 return ans; 68 } 69 /*******************Fenwick*********************/ 70 struct data{ 71 int s,c,m; 72 }a[N]; 73 bool cmp(data a,data b){ 74 if (a.s==b.s){ 75 if (a.c==b.c) return a.m<b.m; 76 return a.c<b.c; 77 } 78 return a.s<b.s; 79 } 80 int ans[N]; 81 int main(){ 82 #ifndef ONLINE_JUDGE 83 freopen("3262.in","r",stdin); 84 freopen("3262.out","w",stdout); 85 #endif 86 n=getint(); k=getint(); 87 F(i,1,n){ 88 a[i].s=getint(); 89 a[i].c=getint(); 90 a[i].m=getint(); 91 } 92 sort(a+1,a+n+1,cmp); 93 int num=1; 94 F(i,1,n){ 95 if (a[i].s==a[i+1].s && 96 a[i].c==a[i+1].c && 97 a[i].m==a[i+1].m) num++; 98 else{ 99 ans[query(a[i].c,a[i].m)+num-1]+=num; 100 update(a[i].c,a[i].m,num); 101 num=1; 102 } 103 } 104 rep(i,n) printf("%d\n",ans[i]); 105 return 0; 106 }