CF558E-A Simple Task-线段树+计数排序

计数排序的原理,只要知道了有几个数比i小,就可以知道i的位置

这道题只有26个字母,搞26颗线段树,然后区间更新

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 //using namespace std;
  6 const int maxn = 1e5+10;
  7 
  8 int N,Q;
  9 char line[maxn];
 10 
 11 #define lson rt<<1,l,mid
 12 #define rson rt<<1|1,mid+1,r
 13 #define root 1,1,N
 14 
 15 struct SegrTree{
 16     int num[maxn<<2];
 17     int lazy[maxn<<2];
 18     void init()
 19     {
 20         memset(lazy,-1,sizeof lazy);
 21     }
 22     void push_up(int rt)
 23     {
 24         num[rt] = num[rt<<1] + num[rt<<1|1];
 25     }
 26     void push_down(int rt,int m)
 27     {
 28         if(lazy[rt] != -1)
 29         {
 30             num[rt<<1] = (m-(m>>1))*lazy[rt] ;
 31             num[rt<<1|1] = (m>>1)*lazy[rt] ;
 32             lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
 33             lazy[rt] = -1;
 34         }
 35     }
 36     void build(int kind,int rt,int l,int r)
 37     {
 38         if(l == r)
 39         {
 40             num[rt] = line[l-1]==kind+'a';
 41             //if(line[l-1]=='c') printf("%c pos:%d \n",kind+'a',l);
 42             return ;
 43         }
 44         int mid = (l+r)>>1;
 45         build(kind,lson);
 46         build(kind,rson);
 47         push_up(rt);
 48     }
 49     void update(int L,int R,int d,int rt,int l,int r)
 50     {
 51         if(L <= l && R >= r)
 52         {
 53             num[rt] = (r-l+1)*d;
 54             lazy[rt] = d;
 55             return ;
 56         }
 57         push_down(rt,r-l+1);
 58         int mid = (l+r)>>1;
 59         if(L <= mid) update(L,R,d,lson);
 60         if(R >  mid) update(L,R,d,rson);
 61         push_up(rt);
 62     }
 63     int query(int L,int R,int rt,int l,int r)
 64     {
 65         if(L <= l && R >= r)
 66         {
 67             return num[rt];
 68         }
 69         push_down(rt,r-l+1);
 70         int mid = (l+r)>>1;
 71         int res = 0;
 72 
 73         if(R <= mid) res = query(L,R,lson);
 74         else if(L > mid) res = query(L,R,rson);
 75         else res = query(L,R,lson)+query(L,R,rson);
 76 
 77         push_up(rt);
 78         return res;
 79     }
 80 }alpha[26];
 81 
 82 void sort(int l,int r,int k)
 83 {
 84     int pos,cnt;
 85     if(k == 1)
 86     {
 87         pos = l;
 88         for(int i=0;i<26;i++)
 89         {
 90             cnt = alpha[i].query(l,r,root);
 91             //printf("[%d,%d]%c k:%d pos:%d cnt:%d\n",l,r,i+'a',k,pos,cnt);
 92             if(cnt)
 93             {
 94                 alpha[i].update(l,r,0,root);
 95                 alpha[i].update(pos,pos+cnt-1,1,root);
 96                 pos += cnt;
 97             }
 98         }
 99     }
100     else
101     {
102         pos = l;
103         for(int i=25;i>=0;i--)
104         {
105             cnt = alpha[i].query(l,r,root);
106             //printf("[%d,%d] %c k:%d pos:%d cnt:%d\n",l,r,i+'a',k,pos,cnt);
107             if(cnt)
108             {
109                 alpha[i].update(l,r,0,root);
110                 alpha[i].update(pos,pos+cnt-1,1,root);
111                 pos += cnt;
112             }
113         }
114     }
115 }
116 
117 int main()
118 {
119     //freopen("input.txt","r",stdin);
120 
121     scanf("%d%d",&N,&Q);
122     scanf("%s",line);
123 
124     for(int i=0;i<26;i++)
125     {
126         alpha[i].init();
127         alpha[i].build(i,root);
128         //printf("tot num:%c %d\n",i+'a',alpha[i].query(1,N,root));
129     }
130     //printf("c:%d c:%d\n",alpha[2].query(1,N,root),alpha[2].query(7,10,root));
131     for(int i=0,l,r,k;i<Q;i++)
132     {
133         scanf("%d%d%d",&l,&r,&k);
134         sort(l,r,k);
135     }
136     for(int i=1;i<=N;i++)
137     {
138         for(int j=0;j<26;j++) if(alpha[j].query(i,i,root))
139         {
140             printf("%c",'a'+j);
141         }
142     }
143     puts("");
144 }

 

posted @ 2016-08-09 11:44  Helica  阅读(231)  评论(0编辑  收藏  举报