pku 2528 Mayor's posters-线段树+离散化

    技术2022-05-14  0

    第一道离散化是题目,不过这离散也太容易了,不用考虑冲突问题,不用记录

    其它距离之类的数据,不过这道题有个囧地方(至少囧到我了),就是树的数组开3*N

    不够,因为我以前都是开3*N,没出现过问题,这题把写完后WA了,真有点无语,

    因为就觉得思路是没问题的,后来百度下,发现别人都开4*N的,后来想了想,上思修时

    在纸上画了差不多一节课,发现根本原因:总的来说对于线段树最坏开到4*N就定没问题

    因为它的结构是一个完全二叉树,当(N-1)是2的n次方是就是情况最差的时候,这时必须

    开4*N才可以,不然下标一写会越界,最好像9那样最后【9,10)这个结点在树中的下标是31!(应该是)

    这次得好好记住才行,以后都开4*N

     

    最后对于这一题和pku 2777差不多,就多了个离散化,而且还是最简单的离散化

    代码:

     

    #include<iostream> #include<cstring> #include<cstdlib> #define N 10005 using namespace std; struct elem { int s; int t; }; struct node { int l; int r; int pos; }; int n,count; elem arr[N]; node tree[8*N]; int index[2*N],len; int mark[N]; int flag; int cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; } void disc() { int i; int a,b; for(i = 0;i < n;i++){ cin >>a >>b; arr[i].s = a; arr[i].t = b; index[2*i] = a;index[2*i+1] = b; } qsort(index,2*n,sizeof(index[0]),cmp); len = 0; for(i = 1;i < 2*n;i++){ if(index[i] != index[i-1]){ index[++len] = index[i]; } } //for(i = 1;i <= len;i++){ // cout <<index[i] <<' '; //} //cout <<endl; return ; } int find(int a) { int mid; int base = 0,top = len; while(base <= top){ mid = (base+top)/2; if(a > index[mid]) base = mid+1; else if(a < index[mid]) top = mid-1; else return mid+1; } return 0; } void buid_tree(int k,int left,int right) {flag = k; int mid; int L,R; tree[k].l = left; tree[k].r = right; tree[k].pos = 0; if(tree[k].r-tree[k].l == 1){ return ; } mid = (tree[k].l+tree[k].r)/2; L = k<<1; R = L+1; buid_tree(L,left,mid); buid_tree(R,mid,right); return ; } void tree_insert(int k,int left,int right,int data) { int mid; int L,R; if(tree[k].pos == data) return ; if(left <= tree[k].l && right >= tree[k].r){ tree[k].pos = data; return; } L = k<<1; R = L+1; if(tree[k].pos){ tree[L].pos = tree[R].pos = tree[k].pos; tree[k].pos = 0; } mid = (tree[k].l+tree[k].r)/2; if(left < mid) tree_insert(L,left,right,data); if(right > mid) tree_insert(R,left,right,data); return ; } void tree_search(int k) { int L,R; if(tree[k].pos){ if(!mark[tree[k].pos]){ count++; mark[tree[k].pos] = 1; } return ; } if(tree[k].r-tree[k].l == 1) return ; L = k<<1; R = L+1; tree_search(L); tree_search(R); return ; } int main() { int tcase; int i; cin >>tcase;//cout <<&count <<' ' <<&tree[60030].r <<endl; while(tcase--){ cin >>n; disc(); buid_tree(1,1,20000+1);cout <<flag <<endl; for(i = 0;i < n;i++){ tree_insert(1,find(arr[i].s),find(arr[i].t)+1,i+1); } memset(mark,0,sizeof(mark)); count = 0; tree_search(1); cout <<count<<endl; } return 0; }


    最新回复(0)