string(线段树)

因为题中只有a-z,所以区间中大量字母都是重复的,我们不妨利用桶的性质。

开一棵树,里面维护当前区间内的相同元素,若区间内元素不同,则为零

每次升序操作就先查询一遍区间,用桶将每个区间的a-z元素统计出,

然后按照顺序(L-L+tong[1]-1)..........进行区间修改,

注意要有向上修改的updata!!!

因为区间有很多字母相同,修改近似是mlogn*26(26次嘛....)查询mlong(n);

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<vector>
  7 #include<map>
  8 #include<cstring>
  9 #define ll long long
 10 #define MAXN 510000
 11 using namespace std;
 12 int read()
 13 {
 14    int x=0;char cc=getchar();
 15    while(cc<'0'||cc>'9'){cc=getchar();}
 16    while(cc>='0'&&cc<='9'){x=(x<<1)+(x<<3)+(cc^48);cc=getchar();}
 17    return x;
 18 }
 19 char s[MAXN];
 20 int tong[MAXN];int n,m;
 21 struct node{int l,r,me;}T[MAXN*4];
 22 void build(int k,int l,int r)
 23 {
 24      T[k].l=l;T[k].r=r;
 25      //printf("l=%d r=%d\n",l,r);
 26      if(l==r)
 27      {
 28          T[k].me=s[l]-'a'+1;
 29          return ;
 30      }
 31      int mid=(l+r)>>1;
 32      build(k<<1,l,mid);
 33      build((k<<1)|1,mid+1,r);
 34      if(T[(k<<1)].me==T[(k<<1)|1].me)
 35      {
 36         T[k].me=T[(k<<1)].me;
 37      }
 38 }
 39 void pushdown(int k)
 40 {
 41      T[k<<1].me=T[k].me;
 42      T[(k<<1)|1].me=T[k].me;
 43      return ;
 44 }
 45 void updata(int k)
 46 {
 47      if(T[k<<1].me==T[(k<<1)|1].me)
 48      T[k].me=T[k<<1].me;
 49      else T[k].me=0;
 50 }
 51 void query(int k,int l,int r)
 52 {
 53      //printf("k=%d l=%d r=%d Tl=%d Tr=%d\n",k,l,r,T[k].l,T[k].r);
 54      if(l<=T[k].l&&r>=T[k].r&&T[k].me!=0)
 55      {
 56          tong[T[k].me]+=T[k].r-T[k].l+1;
 57          return ;
 58      }
 59      if(T[k].l==T[k].r)
 60      {
 61          return ;
 62      }
 63      if(T[k].me)pushdown(k);
 64      int mid=(T[k].l+T[k].r)>>1;
 65      if(l<=mid)query(k<<1,l,r);
 66      if(r>mid)query((k<<1)|1,l,r);
 67      return ;
 68 }
 69 int find(int k,int l)
 70 {
 71      if(T[k].l==T[k].r)
 72      {
 73         // printf("T[k].l=%d T[k].r=%d T[k].me=%d\n",T[k].l,T[k].r,T[k].me);
 74          return T[k].me;
 75      }
 76      if(T[k].me)pushdown(k);
 77      int mid=(T[k].l+T[k].r)>>1;
 78      if(l<=mid)find(k<<1,l);
 79      else find((k<<1)|1,l);
 80 }
 81 void add(int k,int l,int r,int x)
 82 {
 83      if(l<=T[k].l&&r>=T[k].r)
 84      {
 85           T[k].me=x;
 86           //printf("xiugai k=%d l=%d r=%d x=%d\n",k,T[k].l,T[k].r,x);
 87           return ;
 88      }
 89      if(T[k].me)pushdown(k);
 90      int mid=(T[k].l+T[k].r)>>1;
 91      if(l<=mid) add(k<<1,l,r,x);
 92      if(r>mid)  add((k<<1)|1,l,r,x);
 93      updata(k);
 94      //printf("---T[k].me=%d\n",T[13].me);
 95      return ;    
 96 }
 97 void clear(int k,int l,int r)
 98 {
 99      if(l<=T[k].l&&r>=T[k].r)
100      {
101           T[k].me=0;
102      }
103      if(T[k].l==T[k].r)return ;
104      int mid=(T[k].l+T[k].r)>>1;
105      if(l<=mid) clear(k<<1,l,r);
106      if(r>mid)  clear((k<<1)|1,l,r);
107      return ;
108 }
109 void out()
110 {
111      for(int i=1;i<=n;++i)
112      {
113          putchar(find(1,i)+'a'-1);
114      }
115      printf("\n");
116 }
117 void work(int l,int r,int orz)
118 {     //printf("------\n");
119      query(1,l,r);
120      //clear(1,l,r);
121      if(orz==1)
122      {
123           int kx=l;
124           for(int i=1;i<=26;++i)
125           {
126               //printf("tong[%d]=%d\n",i,tong[i]);
127               if(kx+tong[i]-1>=kx)
128               {
129                   //printf("add=%d i=%d\n",kx,i);
130                   add(1,kx,kx+tong[i]-1,i);
131                   //out();
132               }
133               kx+=tong[i];
134           }
135           for(int i=1;i<=26;++i)tong[i]=0;
136      }
137      else
138      {
139           int kx=r;
140           for(int i=1;i<=26;++i)
141           {
142               if(kx-tong[i]+1<=kx)
143               {
144                   add(1,kx-tong[i]+1,kx,i);
145               }
146               kx-=tong[i];
147           }
148           for(int i=1;i<=26;++i)tong[i]=0;
149      }
150      //out();
151 }
152 int main()
153 {
154      //freopen("text.in","r",stdin);
155      //freopen("wa.out","w",stdout);
156      n=read();m=read();
157      scanf("%s",s+1);
158      build(1,1,n);
159      for(int i=1;i<=m;++i)
160      {
161          int l,r,orz;
162          scanf("%d%d%d",&l,&r,&orz);
163          work(l,r,orz);
164      }
165      for(int i=1;i<=n;++i)
166      {
167          putchar(find(1,i)+'a'-1);
168      }
169      printf("\n");
170 }
View Code

猜你喜欢

转载自www.cnblogs.com/Wwb123/p/11287716.html
今日推荐