poj 2528 Mayor's posters

线段树+区间离散化:弄了好久,注意数组范围。

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #define MAXN 10000+100
  5 
  6 int T, n, a[MAXN<<2], b[MAXN<<2], r[MAXN<<2], h[MAXN<<2], to[MAXN<<4];
  7 
  8 int cmp(const void *_p, const void *_q)
  9 {
 10     int *p = (int *)_p;
 11     int *q = (int *)_q;
 12     return a[*p]-a[*q];    
 13 }
 14 
 15 void build(int cur,int x, int y)
 16 {
 17     int mid = (x+y)>>1, ls = cur<<1, rs = cur<<1|1;
 18     to[cur] = -1;
 19     if(x == y) return;
 20     build(ls, x, mid);
 21     build(rs, mid+1, y);
 22 }
 23 
 24 void pushdown(int cur)
 25 {
 26     int ls = cur<<1, rs = cur<<1|1;
 27     if(to[cur] != -1)
 28     {
 29         to[ls] = to[rs] = to[cur];
 30         to[cur] = -1;
 31     }
 32 }
 33 
 34 void color(int cur, int x, int y, int s, int t, int v)
 35 {
 36     int mid = (x+y)>>1, ls = cur<<1, rs = cur<<1|1;
 37     if(x>=s && y<=t)
 38     {
 39         to[cur] = v;
 40         return ;
 41     }
 42     pushdown(cur);
 43     if(mid>=s)
 44         color(ls, x, mid, s, t, v);
 45     if(mid+1<=t)
 46         color(rs, mid+1, y, s, t, v);
 47 }
 48 
 49 void search(int cur, int x, int y, int &ans)
 50 {
 51     int mid = (x+y)>>1, ls = cur<<1, rs = cur<<1|1;
 52     if(to[cur] != -1)
 53     {
 54         if(!h[to[cur]])
 55         {
 56             ans++;//printf("cur=%d\n",cur);
 57             h[to[cur]] = 1;
 58         }
 59         return ;
 60     }
 61     if(x == y) return ;
 62     search(ls, x, mid, ans);
 63     search(rs, mid+1, y, ans);
 64 }
 65 
 66 void init()
 67 {
 68     while(~scanf("%d",&T))
 69     while(T--)
 70     {
 71         scanf("%d",&n);
 72         for(int i = 1; i <= n*2; i ++)
 73         {
 74             scanf("%d",&a[i]);
 75         }
 76         for(int i = 0; i <= n*2; i ++)
 77             r[i] = i;
 78             a[0] = -1;
 79         qsort(r+1, 2*n, sizeof(r[0]), cmp);//for(int i = 0; i <=2*n; i ++)printf("a[r[i]]=%d\n",a[r[i]]);puts("");
 80         int p = 0;
 81         for(int i = 1; i <= 2*n; i ++)
 82         {//printf("a[r[i-1]]=%d a[r[i]]=%d\n",a[r[i-1]], a[r[i]]);
 83             if(a[r[i]]-a[r[i-1]] >= 1) {p += 1;b[r[i]] = p;}
 84             //else if(a[r[i]]-a[r[i-1]] > 1){p += 2; b[r[i]] = p;}
 85             else b[r[i]] = b[r[i-1]];
 86         }//for(int i = 0; i <=2*n; i ++)printf("a[r[i]]=%d\n",b[r[i]]);
 87         build(1,1,p);
 88         int v = 0;
 89         for(int i = 1; i <= 2*n; i += 2)
 90         {
 91             v ++;//printf("b[i]=%d b[i+1]=%d\n",b[i],b[i+1]);
 92             color(1, 1, p, b[i], b[i+1], v);
 93         }//for(int i = 0; i < 30; i ++) printf("i=%d to[i]=%d\n",i,to[i]);
 94         int ans = 0;
 95         memset(h, 0, sizeof(h[0])*(v+10));
 96         search(1, 1, p, ans);
 97         printf("%d\n",ans);
 98     }
 99 }
100 int main()
101 {
102     init();    
103     return 0;
104 }
posted on 2012-08-24 14:08  BFP  阅读(130)  评论(0编辑  收藏  举报