zoukankan      html  css  js  c++  java
  • NOIP模拟测试11「string·matrix·big」

    打的big出了点小问题,maxx初值我设的0然后少了10分

    第二题暴力打炸

    第一题剪了一些没用的枝依然40分

    总分70

    这是一次失败的考试

    string

    想到和序列那个题很像,但我没做序列,考场回忆学长讲课,打不出来。最后我口胡了一个CDQ分治,大概能减很多枝比如之前5 6 修改,之后4 6修改,那么其实你5 6不用改。

    秉承这个思路,我随意打了一个分治,然后依然40分。

    题解

    我们可以维护每一段区间字母个数,维护一个桶,每次询问先把桶求出来,按照顺序排序时我们可以顺序枚举26个字母,进行区间修改,然后按照逆序反过来枚举就好了。这样把修改操作转化为若干个区间修改。但单单这么做我们会T,维护起来也不好维护,各种懒标记很恶心,我们还需要别的特殊姿势,

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

    这样做我们修改和询问就不用递归到儿子节点了,而且这样我们还节省了维护懒标记时间

    那么我们思考如何维护

    修改时

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

    若区间不完全覆盖

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

    代码

    #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
    ",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
    ",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 ***
    ",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
    ",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
    ",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("");
    }

    big

    题解咕咕咕

    代码

    #include<bits/stdc++.h>
    #define ll long long
    #define A 6000000
    using namespace std;
    ll tire[A][2],t[A],sum[A],dl[A],a[A];
    ll tot=1,n,m,maxx=0,ans=0;
    bool pan;
    ll change(ll x){
        return (2*x/(1<<n)+2*x)%(1<<n);
    }
    bool cmp(ll x,ll y){
        return x>y;
    }
    inline void insert(ll x)
    {
        ll p=1;
        for(ll i=1;i<=n;i++)
        {
            ll zan=(x>>(n-i))&1;
    //        printf("zan=%lld tot=%lld
    ",zan,tot);
            if(!tire[p][zan]) tire[p][zan]=++tot;
            p=tire[p][zan];
        }
    }
    inline ll dfs(ll x,ll zhi,ll deep)
    {
        if(deep<0){
            dl[++dl[0]]=zhi;
        }
    //    printf("trie[0][1]=[%lld][%lld] deep=%lld zhi=%lld 1<<=%lld
    ",tire[x][0],tire[x][1],deep,zhi,1ll<<deep);
        if(tire[x][0]&&!tire[x][1])
            dfs(tire[x][0],zhi^(1ll<<deep),deep-1);
        if(!tire[x][0]&&tire[x][1])
            dfs(tire[x][1],zhi^(1ll<<deep),deep-1);
        if(tire[x][0]&&tire[x][1]){
            dfs(tire[x][0],zhi,deep-1);dfs(tire[x][1],zhi,deep-1);
        }
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=m;i++)
            scanf("%lld",&a[i]);
        for(ll i=m;i>=1;i--)
            sum[i]=sum[i+1]^a[i];
        for(ll i=0,now=0;i<=m;i++){
    //        printf("now=%lld  add=%lld
    ",now,now^sum[i+1]);
            now=now^change(a[i]);
            insert(now^sum[i+1]);
        }
    //    printf("1 %lld 0%lld
    ",tire[1][1],tire[1][0]);
        dfs(1,0,n-1);
        sort(dl+1,dl+dl[0]+1,cmp);
        for(ll i=1;i<=dl[0];i++)
        if(dl[i]==dl[1]) ans++;
        printf("%lld
    %lld
    ",dl[1],ans);
    }
    我已没有下降的余地
  • 相关阅读:
    【11.5】生成器进阶--send、close和throw方法
    【11.4】协程是什么?
    【python】IO多路复用(select、poll、epoll)介绍及select、epoll的实现
    【11.3】select+回调+事件循环获取html
    【11.2】C10K问题和io多路复用(select、poll和epoll)
    【11.1】并发、并行、同步、异步、阻塞、非阻塞
    【10.10】进程间通信--Queue、Pipe、Manager
    set autotrace on 报cannot set autotrace 错误解决方法
    通配符获取文件
    日期函数
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11286426.html
Copyright © 2011-2022 走看看