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 }