NOIP simulation test 11 "string · matrix · big."

Hit the big slight problem, maxx I set the initial value of 0 and 10 points less

The second title fight violence fry

The first question cut some useless branches still 40 points

Total 70

This is a failed exam

string

And think of questions like that sequence, but I did not do the sequence, the examination room recalls seniors lectures, with no success. Finally, my mouth Hu a CDQ partition, would be able to reduce a lot of branches such modifications before 56, after 46 modified, then in fact you 56 do not change.

Adhering to this idea, I'm free to play a divide and conquer, then still 40 points.

answer

We can maintain the number of letters each section range, maintaining a barrel, Always ask first seek out the barrel, we can enumerate 26 in alphabetical order when sorted order, a range of changes, and then in reverse order, in turn enumerate just fine . Thus the modification operation to modify into a plurality of intervals. But we will only do T, maintenance is not good maintenance, a variety of very sick labeled lazy, we also need other special posture,

    if(tr[p].a) tr[p<<1].a=tr[p].a,tr[p<<1|1].a=tr[p].a;

To do so would not ask us to modify and recursive node to a son, but we also saves maintenance time lazy mark

So we think about how to maintain

Modify when

    if(tr[p].l>=l&&tr[p].r<=r||tr[p].a==x){
        tr[p].a=x;
        return ;
    }

If the interval does not completely cover

    if(tr[p].a) tr[p<<1].a=tr[p].a,tr[p<<1|1].a=tr[p].a,tr[p].a=0;

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1010101
struct tree{
    ll x,f,a,l,r;
}tr[A];
char s[A];
ll w[A];
ll n,m;
map<ll,char>mp;
void built(ll p,ll l,ll r){
    tr[p].l=l,tr[p].r=r;
    if(l==r){
//        printf("l=%lld s=%lld\n",l,s[l]-'a'+1ll);
        tr[p].a=s[l]-'a'+1;
        return ;
    }
    ll mid=(l+r)>>1;
    built(p<<1,l,mid);
    built(p<<1|1,mid+1,r);
    if(tr[p<<1].a==tr[p<<1|1].a)
        tr[p].a=tr[p<<1].a;
}
void getsum(ll p,ll l,ll r){
//    printf("l=%lld r=%lld l=%lld r=%lld tr[p].a=%lld\n",tr[p].l,tr[p].r,l,r,tr[p].a);
    if(tr[p].l>=l&&tr[p].r<=r&&tr[p].a){
        w[tr[p].a]+=(tr[p].r-tr[p].l + 1);
        return ;
    }
    ll mid=(tr[p].l+tr[p].r)>>1;
    if(tr[p].a) tr[p<<1].a=tr[p].a,tr[p<<1|1].a=tr[p].a;
    if(mid>=l)getsum(p<<1,l,r);
    if(mid<r)getsum(p<<1|1,l,r);
}
void change(ll p,ll l,ll r,ll x){
//    printf("l=%lld r=%lld ***\n",l,r);
    if(tr[p].l>=l&&tr[p].r<=r||tr[p].a==x){
        tr[p].a=x;
        return ;
    }
    ll mid=(tr[p].l+tr[p].r)>>1;
//    printf("tr[%lld]=%lld\n",p,tr[p].a);    
    if(tr[p].a) tr[p<<1].a=tr[p].a,tr[p<<1|1].a=tr[p].a,tr[p].a=0;
    if(mid>=l) change(p<<1,l,r,x);
    if(mid<r) change(p<<1|1,l,r,x);
}
void out(ll p){
//    printf("p=%lld tr[p].a=%lld mp=%c\n",p,tr[p].a,mp[tr[p].a]);
    if(tr[p].a){
        for(ll i=1;i<=tr[p].r-tr[p].l+1;i++)
            printf("%c",(char)mp[tr[p].a]);
        return ;
    }
    out(p<<1);
    out(p<<1|1);
}
void pre(){
    for(ll i=1;i<=26;i++)
        mp[i]='a'+i-1;
    return ;
}
int main(){
    pre();
    scanf("%lld%lld",&n,&m);
    scanf("%s",s+1);
    built(1,1,n);
    for(ll i=1,a,b,c,t;i<=m;i++){
        scanf("%lld%lld%lld",&a,&b,&c);    
        getsum(1,a,b);
        ll l=a;
        if(c){
            for(ll t=1;t<=26;t++)
                if(w[t])
                    change(1,l,l+w[t]-1,t),l=l+w[t],w[t]=0;
        }
        else {
            for(ll t=26;t>=1;t--)
                if(w[t])
                    change(1,l,l+w[t]-1,t),l=l+w[t],w[t]=0;
        }
    }
    out(1);
    puts("");
}

 

Guess you like

Origin www.cnblogs.com/znsbc-13/p/11286426.html