1. 程式人生 > 實用技巧 >python socket 聊天室

python socket 聊天室

string

題目描述

給定一個由小寫字母組成的字串s。有m次操作,每次操作給定3個引數l,r,x 。如果x=1,將 s[l]~s[r]升序排序;如果x=0,將s[l]~s[r]降序排序。你需要求出最終序列。

輸入格式

第一行兩個整數n,m,表示字串長度為n,有m次操作。
第二行一個字串 。
接下來 行每行三個整數l,r,x。

輸出格式

一行一個字串表示答案。

樣例

樣例輸入

5 2
cabcd
1 3 1
3 5 0

樣例輸出

abdcc

資料範圍與提示

對於100%的資料, n,m<=100000

思路:首先想到的是用sort水,不過sort是nlogn,所以只能誰40分。

   正解:線段樹,用線段樹維護一段區間內字母的個數,這時tree[maxn]陣列記錄的不是區間和而是如果tree[rt]統治的區間內符號相同,則tree[rt]為此符號的值類似於lazy標記(這樣做為了優化一下時間效率)

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=100000+10;
 4 char s[maxn];
 5 int tree[maxn<<2],f[maxn],n;
6 void Build(int rt,int l,int r){ 7 if(l==r){ 8 tree[rt]=s[l]-'a'+1;//注意要加1,不然若這個字元為a的話,tree為0,區分不出有沒有字元標記 9 return ; 10 } 11 int mid=(l+r)>>1; 12 Build(rt<<1,l,mid); 13 Build(rt<<1|1,mid+1,r); 14 if(tree[rt<<1]==tree[rt<<1|1]) tree[rt]=tree[rt<<1
];//若左右子樹相等,更新根節點 15 } 16 void pushdown(int rt,int l,int r){ 17 if(tree[rt]){ 18 tree[rt<<1]=tree[rt]; 19 tree[rt<<1|1]=tree[rt]; 20 tree[rt]=0; 21 } 22 } 23 void query(int rt,int l,int r,int s,int t){ 24 if(s<=l&&t>=r&&tree[rt]){//若tree有值,再return 25 f[tree[rt]]+=(r-l+1); 26 return ; 27 } 28 pushdown(rt,l,r); 29 int mid=(l+r)>>1; 30 if(s<=mid) query(rt<<1,l,mid,s,t); 31 if(t>mid) query(rt<<1|1,mid+1,r,s,t); 32 } 33 void Modify(int rt,int l,int r,int s,int t,int w){ 34 if(s<=l&&t>=r||tree[rt]==w){//寫tree[rt]==w,會快一點 35 tree[rt]=w; 36 return; 37 } 38 pushdown(rt,l,r); 39 int mid=(l+r)>>1; 40 if(s<=mid) Modify(rt<<1,l,mid,s,t,w); 41 if(t>mid) Modify(rt<<1|1,mid+1,r,s,t,w); 42 if(tree[rt<<1]==tree[rt<<1|1]) tree[rt]=tree[rt<<1]; 43 } 44 void solve(int l,int r,int x){ 45 memset(f,0,sizeof(f));//記得初始化 46 query(1,1,n,l,r);//查詢每個字母的數量 47 if(x==1){ 48 int sum=l; 49 for(int i=1;i<=26;i++){ 50 if(f[i]){ 51 Modify(1,1,n,sum,sum+f[i]-1,i); 52 sum+=f[i]; 53 } 54 } 55 }//正序,正著列舉 56 else{ 57 int sum=l; 58 for(int i=26;i>=1;i--){ 59 if(f[i]){ 60 Modify(1,1,n,sum,sum+f[i]-1,i); 61 sum+=f[i]; 62 } 63 } 64 }//倒序,倒著列舉 65 } 66 void print(int rt,int l,int r){ 67 if(tree[rt]){ 68 for(int i=l;i<=r;i++){ 69 printf("%c",tree[rt]+'a'-1); 70 } 71 return; 72 } 73 int mid=(l+r)>>1; 74 print(rt<<1,l,mid); 75 print(rt<<1|1,mid+1,r); 76 } 77 int main(){ 78 int m; 79 scanf("%d%d",&n,&m); 80 scanf("%s",s+1); 81 Build(1,1,n); 82 for(int i=1;i<=m;i++){ 83 int l,r,x; 84 scanf("%d%d%d",&l,&r,&x); 85 solve(l,r,x); 86 } 87 print(1,1,n); 88 printf("\n"); 89 return 0; 90 }
View Code