码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 558EA Simple Task

时间:2015-08-03 10:10:15      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

开始试想直接用容器来暴力做,,,,,,

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

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

先来个模板先(就是那种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;
      
       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;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

codeforces 558EA Simple Task

标签:

原文地址:http://blog.csdn.net/zhangwenchi/article/details/47251423

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!