POJ 2201 笛卡尔树+RMQ
题意:
题目大意:
让你构造一棵笛卡尔树。
笛卡尔树的节点含有2个值,1个key,一个value,其中key是主键,value是辅键。一棵笛卡尔树就是:key升序,value升序或者降序。类似堆。
判断能否构成。(PS:此题保证数据相异,必然能够成)
思路:
第一次做,参考的别人的,不过这个模板好像写的有点别扭。。
自我感觉思路比较清晰的模板见我的下一篇文章:http://www.cnblogs.com/proverbs/archive/2012/10/11/2720592.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 7 #define N 200000 8 9 using namespace std; 10 11 struct PO 12 { 13 int a,w,id; 14 }po[N]; 15 16 struct TREE 17 { 18 int u,l,r; 19 }tr[N*2]; 20 21 int pn[N][20],lg[N],n; 22 23 inline bool cmp(const PO &a,const PO &b) 24 { 25 return a.a<b.a; 26 } 27 28 inline int jmin(int x,int y) 29 { 30 if(po[x].w>po[y].w) return y; 31 else return x; 32 } 33 34 inline int askmin(int l,int r) 35 { 36 int k=lg[r-l+1]; 37 return jmin(pn[l][k],pn[r-(1<<k)+1][k]); 38 } 39 40 void init_rmq() 41 { 42 for(int i=1;i<=n;i++) pn[i][0]=i; 43 for(int j=1;(1<<j)<=n;j++) 44 for(int i=1;i+(1<<j)-1<=n;i++) 45 pn[i][j]=jmin(pn[i][j-1],pn[i+(1<<(j-1))][j-1]); 46 } 47 48 void read() 49 { 50 for(int i=1;i<=n;i++) 51 { 52 scanf("%d%d",&po[i].a,&po[i].w); 53 po[i].id=i; 54 } 55 sort(po+1,po+1+n,cmp); 56 init_rmq(); 57 } 58 59 int create(int u,int l,int r) 60 { 61 if(l>r) return 0; 62 int pos=askmin(l,r); 63 int sta=po[pos].id; 64 tr[sta].u=u; 65 tr[sta].l=create(sta,l,pos-1); 66 tr[sta].r=create(sta,pos+1,r); 67 return sta; 68 } 69 70 void go() 71 { 72 create(0,1,n); 73 puts("YES"); 74 for(int i=1;i<=n;i++) 75 printf("%d %d %d\n",tr[i].u,tr[i].l,tr[i].r); 76 } 77 78 int main() 79 { 80 for(int i=1;i<N;i++) 81 lg[i]=(i>>lg[i-1]+1)?lg[i-1]+1:lg[i-1]; 82 while(scanf("%d",&n)!=EOF) 83 { 84 read(); 85 go(); 86 } 87 return 0; 88 }
没有人能阻止我前进的步伐,除了我自己!