您的位置:首页 > 其它

codeforces 558EA Simple Task

2015-08-03 09:40 337 查看
开始试想直接用容器来暴力做,,,,,,

恩。。。。。线段树。。。。

记不得以前写没写过了,,,,

先来个模板先(就是那种n个询问成段更新的题)

#include<stdio.h>

#include<string.h>

#include <algorithm>

#include <bits/stdc++.h>

using namespace std;

 

    

#define lson l , m , rt << 1   

#define rson m + 1 , r , rt << 1 | 1  

#define root 1 , N , 1  

#define LL long long   

const int maxn = 111111;   

LL add[maxn<<2];   

LL sum[maxn<<2];   

void PushUp(int rt) {   

    sum[rt] = sum[rt<<1] + sum[rt<<1|1];   

}   

void PushDown(int rt,int m) {   

    if (add[rt])

    {   

        add[rt<<1] += add[rt];   

        add[rt<<1|1] += add[rt];   

        sum[rt<<1] += add[rt] * (m - (m >> 1));   

        sum[rt<<1|1] += add[rt] * (m >> 1);   

        add[rt] = 0;   

    }   

}   

void build(int l,int r,int rt)

{   

    add[rt] = 0;   

    if (l == r) {   

        scanf("%lld",&sum[rt]);   

        return ;   

    }   

    int m = (l + r) >> 1;   

    build(lson);   

    build(rson);   

    PushUp(rt);   

}   

void update(int L,int R,int c,int l,int r,int rt) {   

    if (L <= l && r <= R) {   

        add[rt] += c;   

        sum[rt] += (LL)c * (r - l + 1);   

        return ;   

    }   

    PushDown(rt , r - l + 1);   

    int m = (l + r) >> 1;   

    if (L <= m) update(L , R , c , lson);   

    if (m < R) update(L , R , c , rson);   

    PushUp(rt);   

}   

LL query(int L,int R,int l,int r,int rt) {   

    if (L <= l && r <= R) {   

        return sum[rt];   

    }   

    PushDown(rt , r - l + 1);   

    int m = (l + r) >> 1;   

    LL ret = 0;   

       if (L <= m) ret += query(L , R , lson);   

       if (m < R) ret += query(L , R , rson);   

    return ret;   

}   

int main() {   

    int N , Q;   

    scanf("%d%d",&N,&Q);   

    build(root);   

    while (Q --) {   

        char op[2];   

        int a , b , c;   

        scanf("%s",op);   

        if (op[0] == 'Q') {   

            scanf("%d%d",&a,&b);   

            printf("%lld\n",query(a , b ,root));   

        } else {   

            scanf("%d%d%d",&a,&b,&c);   

            update(a , b , c , root);   

        }   

    }   

    return 0;   

}

/*我们开26棵线段树,第i棵线段树维护的是:26个字母中排第i个的字母在各个区间的数目。*/

#include<iostream>

#include<cstring>

#include<string>

using namespace std;

int aint[400005][27], lazy[400005], i, x, y, op, n, q, aux[27], paux;

string s;

void init(int nod, int l, int r) {

    if (l==r) aint[nod][int(s[l-1]-'a')]=1;

 else {

    int mid=(l+r)/2;

   

    init(2*nod,l,mid);

    init(2*nod+1,mid+1,r);

   

    for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod][i]+aint[2*nod+1][i];

 

    }

}

void buildsol(int nod, int l, int r) {

   if (lazy[nod]==1) {//update crescator pe fii

       int p=0, nr=aint[nod][0];

       int mid=(l+r)/2;

       int leftlen=mid-l+1;

    
4000
  

       memset(aint[2*nod],0,sizeof(aint[2*nod]));

       memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

      

       while (nr<=leftlen) {

          aint[2*nod][p]=aint[nod][p];

          ++p;

          nr+=aint[nod][p];

       }

      

       nr-=aint[nod][p];

       if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

       if (leftlen>1) lazy[2*nod]=1;

      

       aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

       ++p;

       while (p<26) {

          aint[2*nod+1][p]=aint[nod][p];

          ++p;

       }

       if (r-mid>1) lazy[2*nod+1]=1;

       lazy[nod]=0;

   }

   else if (lazy[nod]==2) {//update descrescator pe fii

       int p=25, nr=aint[nod][25];

       int mid=(l+r)/2;

       int leftlen=mid-l+1;

      

       memset(aint[2*nod],0,sizeof(aint[2*nod]));

       memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

      

       while (nr<=leftlen) {

          aint[2*nod][p]=aint[nod][p];

          --p;

          nr+=aint[nod][p];

       }

      

       nr-=aint[nod][p];

       if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

       if (leftlen>1) lazy[2*nod]=2;

      

       aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

       --p;

       while (p>=0) {

          aint[2*nod+1][p]=aint[nod][p];

          --p;

       }

       if (r-mid>1) lazy[2*nod+1]=2;

       lazy[nod]=0;

   }

 

   if (l==r) {

       int k=0;

       while (aint[nod][k]==0) ++k;

       s+=char(k+'a');

    }

    else {

       int mid=(l+r)/2;

   

    buildsol(2*nod,l,mid);

    buildsol(2*nod+1,mid+1,r); 

     

    }

 

}

void getnumbers(int nod, int l, int r, int x, int y) {

  

   if (lazy[nod]==1) {//update crescator pe fii

       int p=0, nr=aint[nod][0];

       int mid=(l+r)/2;

       int leftlen=mid-l+1;

      

       memset(aint[2*nod],0,sizeof(aint[2*nod]));

       memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

      

       while (nr<=leftlen) {

          aint[2*nod][p]=aint[nod][p];

          ++p;

          nr+=aint[nod][p];

       }

      

       nr-=aint[nod][p];

       if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

       if (leftlen>1) lazy[2*nod]=1;

      

       aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

       ++p;

       while (p<26) {

          aint[2*nod+1][p]=aint[nod][p];

          ++p;

       }

       if (r-mid>1) lazy[2*nod+1]=1;

       lazy[nod]=0;

   }

   else if (lazy[nod]==2) {//update descrescator pe fii

      int p=25, nr=aint[nod][25];

       int mid=(l+r)/2;

       int leftlen=mid-l+1;

      

       memset(aint[2*nod],0,sizeof(aint[2*nod]));

       memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

      

       while (nr<=leftlen) {

          aint[2*nod][p]=aint[nod][p];

          --p;

          nr+=aint[nod][p];

       }

      

       nr-=aint[nod][p];

       if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

       if (leftlen>1) lazy[2*nod]=2;

      

       aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

       --p;

       while (p>=0) {

          aint[2*nod+1][p]=aint[nod][p];

          --p;

       }

       if (r-mid>1) lazy[2*nod+1]=2;

       lazy[nod]=0;

   }

  

   if (l>=x&&r<=y) {

      for (int i=0; i<=25; ++i) aux[i]+=aint[nod][i];

   }

   else {

      int mid=(l+r)/2;

    

      if (x<=mid) getnumbers(2*nod,l,mid,x,y);

      if (y>mid) getnumbers(2*nod+1,mid+1,r,x,y);

   }

  

}

void updatecresc(int nod, int l, int r,int x, int y) {

  

   if (l>=x&&r<=y) {

     

      for (int i=0; i<26; ++i) aint[nod][i]=0;

     

      int nr=aux[paux];

      int len=(r-l+1);

     

      while (nr<=len&&paux<=25) {

         aint[nod][paux]=aux[paux];

   ++paux;

   nr+=aux[paux]; 

      }

     

      if (paux<=25) {

         nr-=aux[paux];

   if (nr<len) aint[nod][paux]=len-nr;

   aux[paux]-=(len-nr); 

        if (aux[paux]==0) ++paux;

      }

     

      if (l<r) lazy[nod]=1;

  

   }

   else {

      int mid=(l+r)/2;

      if (x<=mid) updatecresc(2*nod,l,mid,x,y);

      if (y>mid) updatecresc(2*nod+1,mid+1,r,x,y);

     

      for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod+1][i]+aint[2*nod][i];

   }

   

}

void updatedesc(int nod, int l, int r, int x, int y) {

 

 if (l>=x&&r<=y) {

     

      for (int i=0; i<26; ++i) aint[nod][i]=0;

     

      int nr=aux[paux];

      int len=(r-l+1);

     

      while (nr<=len&&paux>=0) {

         aint[nod][paux]=aux[paux];

   --paux;

   if (paux>=0) nr+=aux[paux]; 

      }

     

      if (paux>=0) {

         nr-=aux[paux];

   if (nr<len) aint[nod][paux]=len-nr;

   aux[paux]-=(len-nr); 

        if (aux[paux]==0) --paux;

      }

     

      if (l<r) lazy[nod]=2;

  

   }

   else {

      int mid=(l+r)/2;

      if (x<=mid) updatedesc(2*nod,l,mid,x,y);

      if (y>mid) updatedesc(2*nod+1,mid+1,r,x,y);

     

      for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod+1][i]+aint[2*nod][i];

   }

 

}

void sortcresc(int x, int y) {

  

   memset(aux,0,sizeof(aux));

   getnumbers(1,1,n,x,y);

   paux=0;

   updatecresc(1,1,n,x,y);

  

}

void sortdesc(int x, int y) {

   memset(aux,0,sizeof(aux));

   getnumbers(1,1,n,x,y);

   paux=25;

   updatedesc(1,1,n,x,y); 

}

int main(void) {

 

 cin>>n>>q;

 getline(cin,s);

 getline(cin,s);

 

 init(1,1,n);

 

 for (; q; --q) {

  

  cin>>x>>y>>op;

  

  if (op==1) sortcresc(x,y);

  else sortdesc(x,y);

  

 }

 

 s="";

 buildsol(1,1,n);

 

 cout<<s;

 

 return 0;

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: