【Vjudge】P558E A Simple Task(线段树暴力)

  题目链接

  这题……太暴力了吧……

  开二十六棵线段树维护l到r字符i出现的次数,然后修改的时候暴力修改,输出的时候暴力输出……就过了……

  然后我还没想到……

  qwq

  

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<algorithm>
#define maxn 100050
#define left (rt<<1)
#define right (rt<<1|1)
#define mid ((l+r)>>1)
#define lson l,mid,left
#define rson mid+1,r,right
using namespace std;

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

inline int count(char c){    return c-'a'+1;    }

char q[maxn];

struct Segtree{
    int tree[maxn*5];
    int tag[maxn*5];
    int mem[maxn*5];
    inline void pushup(int rt){
        tree[rt]=tree[left]+tree[right];
    }
    void build(int l,int r,int rt,int o){
        tree[rt]=tag[rt]=0;    mem[rt]=-1;
        if(l==r){
            tree[rt]=count(q[l])==o?1:0;
            return;
        }
        build(lson,o);
        build(rson,o);
        pushup(rt);
        return;
    }
    void pushdown(int rt,int m){
        if(tag[rt]==0&&mem[rt]==-1)    return;
        if(mem[rt]!=-1){
            mem[left]=mem[right]=mem[rt];
            tag[left]=tag[right]=0;
            tree[left]=mem[rt]*(m-(m>>1));
            tree[right]=mem[rt]*(m>>1);
            mem[rt]=-1;
        }
        if(tag[rt]){
            tag[left]+=tag[rt];
            tag[right]+=tag[rt];
            tree[left]+=tag[rt]*(m-(m>>1));
            tree[right]+=tag[rt]*(m>>1);
            tag[rt]=0;
        }
    }
    void update(int from,int to,int num,int l,int r,int rt){
        if(from<=l&&to>=r){
            tree[rt]+=num*(r-l+1);
            tag[rt]=num;
            return;
        }
        pushdown(rt,r-l+1);
        if(from<=mid)    update(from,to,num,lson);
        if(to>mid)        update(from,to,num,rson);
        pushup(rt);
        return;
    }
    void memseg(int from,int to,int l,int r,int rt){
        if(from<=l&&to>=r){
            tree[rt]=0;
            mem[rt]=0;    tag[rt]=0;
            return;
        }
        pushdown(rt,r-l+1);
        if(from<=mid)    memseg(from,to,lson);
        if(to>mid)        memseg(from,to,rson);
        pushup(rt);
        return;
    }
    int query(int from,int to,int l,int r,int rt){
        if(from<=l&&to>=r)    return tree[rt];
        pushdown(rt,r-l+1);
        int ans=0;
        if(from<=mid)    ans+=query(from,to,lson);
        if(to>mid)        ans+=query(from,to,rson);
        return ans;
    }
}s[28];

int d[28];

int main(){
    int n=read(),m=read();
    scanf("%s",q+1);
    for(int i=1;i<=26;++i)    s[i].build(1,n,1,i);
    while(m--){
        int from=read(),to=read(),opt=read();
        for(int i=1;i<=26;++i){
            d[i]=s[i].query(from,to,1,n,1);
            s[i].memseg(from,to,1,n,1);
        }
        if(opt){
            int pos=from;
            for(int i=1;i<=26;++i){
                if(d[i]==0)    continue;
                s[i].update(pos,pos+d[i]-1,1,1,n,1);
                pos+=d[i];
            }
        }
        else{
            int pos=to;
            for(int i=1;i<=26;++i){
                if(d[i]==0)    continue;
                s[i].update(pos-d[i]+1,pos,1,1,n,1);
                pos-=d[i];
            }
        }
    }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=26;++j)
            if(s[j].query(i,i,1,n,1)==1){
                printf("%c",j+'a'-1);
                break;
            }
    return 0;
}

 

https://vjudge.net/problem/CodeForces-558E

posted @ 2018-01-23 11:35  Konoset  阅读(188)  评论(0编辑  收藏  举报