zoukankan      html  css  js  c++  java
  • 【模拟8.01】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
    ",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
    ",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
    ",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
    ",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
    ",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("
    ");
    116 }
    117 void work(int l,int r,int orz)
    118 {     //printf("------
    ");
    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
    ",i,tong[i]);
    127               if(kx+tong[i]-1>=kx)
    128               {
    129                   //printf("add=%d i=%d
    ",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("
    ");
    170 }
    View Code
  • 相关阅读:
    我要好offer之 二叉树大总结
    我要好offer之 字符串相关大总结
    楼层扔鸡蛋问题[转]
    Linux System Programming 学习笔记(十一) 时间
    Linux System Programming 学习笔记(十) 信号
    Linux System Programming 学习笔记(九) 内存管理
    Linux System Programming 学习笔记(八) 文件和目录管理
    Linux System Programming 学习笔记(七) 线程
    Linux System Programming 学习笔记(六) 进程调度
    APUE 学习笔记(十一) 网络IPC:套接字
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11287716.html
Copyright © 2011-2022 走看看