程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> CF 240F TorCoder(線段樹)

CF 240F TorCoder(線段樹)

編輯:C++入門知識

題意:給出一個字符串,有m次操作,每次給出一個區間,把區間重新調整成一個回文序列,如果有多種操作,選擇字典序最小的。如果不能操作則不操作。最後輸出最終的字符串     剛入手,感覺好神奇的題,其實要自己多思考。想一下,其實還是很簡單的。 首先我們統計一下區間內各個字母的數量,然後比較區間長度的奇偶性,就知道是否 可以操作。 面對於回文串的字典序最小,顯然是確定,只需要從小到大枚舉26個字母就行了。 所以做法是:線段樹統計區間內各個字母的數量 然後根據區間長度的奇偶性,判斷是否可以操作。 如果可以操作,就進行對稱的區間更新。 注意個細節:對於如果是區間長度是奇數的,那麼肯定有且只有一種字母的個數是奇數,那麼肯定這個字母位於中間,然後其它字母還是按照字母順序,兩邊更新。 大概的每次更新的復雜度是大概查詢是26*lgn,然後更新是26*lgn,大概跑了2.5s [cpp] #include<iostream>    #include<cstdio>    #include<cstring>    #define mem(a,b) memset(a,b,sizeof(a))    #define N 100005    #define lson step<<1    #define rson step<<1|1    using namespace std;   struct Seg_tree{       int left,right;       int cnt[26],lazy;   }L[N<<2];   int n,m;   char str[N];   int cnt[26];   void push_up(int step){       for(int i=0;i<26;i++)           L[step].cnt[i]=L[lson].cnt[i]+L[rson].cnt[i];   }   void update(int step,int l,int r,int k);   void push_down(int step){       if(L[step].lazy!=-1){           int l=L[step].left,r=L[step].right,m=(l+r)>>1;           update(lson,l,m,L[step].lazy);           update(rson,m+1,r,L[step].lazy);           L[step].lazy=-1;       }   }   void bulid(int step,int l,int r){       L[step].left=l;       L[step].right=r;       L[step].lazy=-1;       mem(L[step].cnt,0);       if(l==r){           L[step].cnt[str[l]-'a']++;           L[step].lazy=str[l]-'a';           return ;       }       int m=(l+r)>>1;       bulid(lson,l,m);       bulid(rson,m+1,r);       push_up(step);   }   void query(int step,int l,int r){       if(L[step].left==l&&L[step].right==r){           for(int i=0;i<26;i++)               cnt[i]+=L[step].cnt[i];           return ;       }       int m=(L[step].left+L[step].right)>>1;       push_down(step);       if(r<=m) query(lson,l,r);       else if(l>m) query(rson,l,r);       else {           query(lson,l,m);           query(rson,m+1,r);       }   }   void update(int step,int l,int r,int k){       if(L[step].left==l&&L[step].right==r){           mem(L[step].cnt,0);           L[step].cnt[k]=r-l+1;           L[step].lazy=k;           return ;       }       push_down(step);       int m=(L[step].left+L[step].right)>>1;       if(r<=m) update(lson,l,r,k);       else if(l>m) update(rson,l,r,k);       else {           update(lson,l,m,k);           update(rson,m+1,r,k);       }       push_up(step);   }   void slove(int step){       if(L[step].left==L[step].right){           putchar(L[step].lazy+'a');           return ;       }       push_down(step);       slove(lson);       slove(rson);   }   int main(){       freopen("input.txt","r",stdin);       freopen("output.txt","w",stdout);       scanf("%d%d%s",&n,&m,str+1);       bulid(1,1,n);       while(m--){           int l,r;           scanf("%d%d",&l,&r);           mem(cnt,0);           query(1,l,r);           if((r-l+1)&1){               int k=0,p;               for(int i=0;i<26;i++)                   if(cnt[i]&1) k++,p=i;               if(k==1){                   int a=l,b=r;                   cnt[p]--;                   for(int i=0;i<26;i++){                       if(cnt[i]){                           update(1,a,a+cnt[i]/2-1,i);                           update(1,b-cnt[i]/2+1,b,i);                           a+=cnt[i]/2;                           b-=cnt[i]/2;                       }                   }                   update(1,a,b,p);               }           }           else{               int k=0;               for(int i=0;i<26;i++)                   if(cnt[i]&1){                       k=1;                       break;                   }               if(!k){                   int a=l,b=r;                   for(int i=0;i<26;i++){                       if(cnt[i]){                           update(1,a,a+cnt[i]/2-1,i);                           update(1,b-cnt[i]/2+1,b,i);                           a+=cnt[i]/2;                           b-=cnt[i]/2;                       }                   }               }           }       }       slove(1);putchar('\n');       return 0;   }     #include<iostream> #include<cstdio> #include<cstring> #define mem(a,b) memset(a,b,sizeof(a)) #define N 100005 #define lson step<<1 #define rson step<<1|1 using namespace std; struct Seg_tree{     int left,right;     int cnt[26],lazy; }L[N<<2]; int n,m; char str[N]; int cnt[26]; void push_up(int step){     for(int i=0;i<26;i++)         L[step].cnt[i]=L[lson].cnt[i]+L[rson].cnt[i]; } void update(int step,int l,int r,int k); void push_down(int step){     if(L[step].lazy!=-1){         int l=L[step].left,r=L[step].right,m=(l+r)>>1;         update(lson,l,m,L[step].lazy);         update(rson,m+1,r,L[step].lazy);         L[step].lazy=-1;     } } void bulid(int step,int l,int r){     L[step].left=l;     L[step].right=r;     L[step].lazy=-1;     mem(L[step].cnt,0);     if(l==r){         L[step].cnt[str[l]-'a']++;         L[step].lazy=str[l]-'a';         return ;     }     int m=(l+r)>>1;     bulid(lson,l,m);     bulid(rson,m+1,r);     push_up(step); } void query(int step,int l,int r){     if(L[step].left==l&&L[step].right==r){         for(int i=0;i<26;i++)             cnt[i]+=L[step].cnt[i];         return ;     }     int m=(L[step].left+L[step].right)>>1;     push_down(step);     if(r<=m) query(lson,l,r);     else if(l>m) query(rson,l,r);     else {         query(lson,l,m);         query(rson,m+1,r);     } } void update(int step,int l,int r,int k){     if(L[step].left==l&&L[step].right==r){         mem(L[step].cnt,0);         L[step].cnt[k]=r-l+1;         L[step].lazy=k;         return ;     }     push_down(step);     int m=(L[step].left+L[step].right)>>1;     if(r<=m) update(lson,l,r,k);     else if(l>m) update(rson,l,r,k);     else {         update(lson,l,m,k);         update(rson,m+1,r,k);     }     push_up(step); } void slove(int step){     if(L[step].left==L[step].right){         putchar(L[step].lazy+'a');         return ;     }     push_down(step);     slove(lson);     slove(rson); } int main(){     freopen("input.txt","r",stdin);     freopen("output.txt","w",stdout);     scanf("%d%d%s",&n,&m,str+1);     bulid(1,1,n);     while(m--){         int l,r;         scanf("%d%d",&l,&r);         mem(cnt,0);         query(1,l,r);         if((r-l+1)&1){             int k=0,p;             for(int i=0;i<26;i++)                 if(cnt[i]&1) k++,p=i;             if(k==1){                 int a=l,b=r;                 cnt[p]--;                 for(int i=0;i<26;i++){                     if(cnt[i]){                         update(1,a,a+cnt[i]/2-1,i);                         update(1,b-cnt[i]/2+1,b,i);                         a+=cnt[i]/2;                         b-=cnt[i]/2;                     }                 }                 update(1,a,b,p);             }         }         else{             int k=0;             for(int i=0;i<26;i++)                 if(cnt[i]&1){                     k=1;                     break;                 }             if(!k){                 int a=l,b=r;                 for(int i=0;i<26;i++){                     if(cnt[i]){                         update(1,a,a+cnt[i]/2-1,i);                         update(1,b-cnt[i]/2+1,b,i);                         a+=cnt[i]/2;                         b-=cnt[i]/2;                     }                 }             }         }     }     slove(1);putchar('\n');     return 0; }  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved