zoukankan      html  css  js  c++  java
  • 20190801考试反思

      这次考试可以说是  极其失败。首先在下午一开始拿到题,头脑不清,夜不能寐,辗转反侧,积劳成疾,胡思乱想。看一眼T1,????学长讲过?我又没做???完了完了,好像是什么二分建树,先打个暴力再说,这个暴力挺好打,打完过样例20min,看T2:?????????方案数??完了图论方案数,心里阴影「奇怪的道路」。先打个暴力再说,dfs一波,打完40min,看T3:????????位运算,异或???手动吃屎。先……打个暴力?枚举一波,打完60min,一看表,好吧开始想正解吧。想了一会200min。。。。收卷。然后获得了出题人有手就送的暴力分。想了两个半小时以后啥也没想出来。。。

      T1:线段树维护桶排序,然后26次赋值。。。手动排序,理论复杂度$O(mlogn)$极其友好,然而可见常数就有$26^{2}$,而且教练不给开氧,于是我们就各种神仙操作,其中最有效的是26次循环展开,代码令人心疼

      

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int N=100020;
    char op[N];
    int bin[30];
    struct node
    {
        int tin[30];
        int &operator [](int x){return tin[x];}
        node operator +(node b)
        {
            node c;c.clear();
            for(int i=0;i<26;i++)
                c[i]=tin[i]+b[i];
            return c;
        }
        void clear(){memset(tin,0,sizeof(tin));}
        void print()
        {
            for(int i=0;i<26;i++)
                printf("%d %d
    ",i,tin[i]);
            puts("");
        }
    };
    struct tree{int l,r,w,f;node bin;}tr[N*4];
    inline int rd()
    {
        int s=0,w=1;
        char cc=getchar();
        while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();}
        while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar();
        return s*w;
    }
    void change(int k,int w)
    {
        tr[k].w=(tr[k].r-tr[k].l+1)*w;
        tr[k].f=w;
        tr[k].bin[0]=0;
        tr[k].bin[1]=0;
        tr[k].bin[2]=0;
        tr[k].bin[3]=0;
        tr[k].bin[4]=0;
        tr[k].bin[5]=0;
        tr[k].bin[6]=0;
        tr[k].bin[7]=0;
        tr[k].bin[8]=0;
        tr[k].bin[9]=0;
        tr[k].bin[10]=0;
        tr[k].bin[11]=0;
        tr[k].bin[12]=0;
        tr[k].bin[13]=0;
        tr[k].bin[14]=0;
        tr[k].bin[15]=0;
        tr[k].bin[16]=0;
        tr[k].bin[17]=0;
        tr[k].bin[18]=0;
        tr[k].bin[19]=0;
        tr[k].bin[20]=0;
        tr[k].bin[21]=0;
        tr[k].bin[22]=0;
        tr[k].bin[23]=0;
        tr[k].bin[24]=0;
        tr[k].bin[25]=0;
        tr[k].bin[w]=tr[k].r-tr[k].l+1;
    }
    void updata(int k)
    {
        tr[k].w=tr[k<<1].w+tr[k<<1|1].w;
        tr[k].bin[0]=tr[k<<1].bin[0]+tr[k<<1|1].bin[0];
        tr[k].bin[1]=tr[k<<1].bin[1]+tr[k<<1|1].bin[1];
        tr[k].bin[2]=tr[k<<1].bin[2]+tr[k<<1|1].bin[2];
        tr[k].bin[3]=tr[k<<1].bin[3]+tr[k<<1|1].bin[3];
        tr[k].bin[4]=tr[k<<1].bin[4]+tr[k<<1|1].bin[4];
        tr[k].bin[5]=tr[k<<1].bin[5]+tr[k<<1|1].bin[5];
        tr[k].bin[6]=tr[k<<1].bin[6]+tr[k<<1|1].bin[6];
        tr[k].bin[7]=tr[k<<1].bin[7]+tr[k<<1|1].bin[7];
        tr[k].bin[8]=tr[k<<1].bin[8]+tr[k<<1|1].bin[8];
        tr[k].bin[9]=tr[k<<1].bin[9]+tr[k<<1|1].bin[9];
        tr[k].bin[10]=tr[k<<1].bin[10]+tr[k<<1|1].bin[10];
        tr[k].bin[11]=tr[k<<1].bin[11]+tr[k<<1|1].bin[11];
        tr[k].bin[12]=tr[k<<1].bin[12]+tr[k<<1|1].bin[12];
        tr[k].bin[13]=tr[k<<1].bin[13]+tr[k<<1|1].bin[13];
        tr[k].bin[14]=tr[k<<1].bin[14]+tr[k<<1|1].bin[14];
        tr[k].bin[15]=tr[k<<1].bin[15]+tr[k<<1|1].bin[15];
        tr[k].bin[16]=tr[k<<1].bin[16]+tr[k<<1|1].bin[16];
        tr[k].bin[17]=tr[k<<1].bin[17]+tr[k<<1|1].bin[17];
        tr[k].bin[18]=tr[k<<1].bin[18]+tr[k<<1|1].bin[18];
        tr[k].bin[19]=tr[k<<1].bin[19]+tr[k<<1|1].bin[19];
        tr[k].bin[20]=tr[k<<1].bin[20]+tr[k<<1|1].bin[20];
        tr[k].bin[21]=tr[k<<1].bin[21]+tr[k<<1|1].bin[21];
        tr[k].bin[22]=tr[k<<1].bin[22]+tr[k<<1|1].bin[22];
        tr[k].bin[23]=tr[k<<1].bin[23]+tr[k<<1|1].bin[23];
        tr[k].bin[24]=tr[k<<1].bin[24]+tr[k<<1|1].bin[24];
        tr[k].bin[25]=tr[k<<1].bin[25]+tr[k<<1|1].bin[25];
    }
    void down(int k)
    {
        change(k<<1,tr[k].f);
        change(k<<1|1,tr[k].f);
        tr[k].f=-1;
    }
    void build(int k,int l,int r)
    {
        tr[k].l=l,tr[k].r=r;
        if(l==r){tr[k].w=op[l]-'a';tr[k].bin[tr[k].w]++;return ;}
        int mid=l+r>>1;
        tr[k].f=-1;
        tr[k].bin.clear();
        build(k<<1,l,mid);build(k<<1|1,mid+1,r);
        updata(k);
    }
    int ask(int k,int id)
    {
        int l=tr[k].l,r=tr[k].r,mid=l+r>>1;
        if(l==r) return tr[k].w;
        if(tr[k].f!=-1) down(k);
        if(id<=mid) return ask(k<<1,id);
        else return ask(k<<1|1,id);
    }
    node query(int k,int x,int y)
    {
        int l=tr[k].l,r=tr[k].r,mid=l+r>>1;
        if(l==x&&r==y) return tr[k].bin;
        if(tr[k].f!=-1) down(k);
        if(y<=mid) return query(k<<1,x,y);
        else if(x>mid) return query(k<<1|1,x,y);
        return query(k<<1,x,mid)+query(k<<1|1,mid+1,y);
    }
    void add(int k,int x,int y,int w)
    {
        int l=tr[k].l,r=tr[k].r,mid=l+r>>1;
        if(x==l&&r==y){change(k,w);return ;}
        if(tr[k].f!=-1) down(k);
        if(y<=mid) add(k<<1,x,y,w);
        else if(x>mid) add(k<<1|1,x,y,w);
        else add(k<<1,x,mid,w),add(k<<1|1,mid+1,y,w);
        updata(k);
    }
    inline void binsort(int l,int r,int x)
    {
        node c=query(1,l,r);
        int k=l;
        for(int i=0;i<26;i++)bin[i]=c[i];
        if(x)
        {
        if(bin[0]){add(1,k,k+bin[0]-1,0);k+=bin[0];}
        if(bin[1]){add(1,k,k+bin[1]-1,1);k+=bin[1];}
        if(bin[2]){add(1,k,k+bin[2]-1,2);k+=bin[2];}
        if(bin[3]){add(1,k,k+bin[3]-1,3);k+=bin[3];}
        if(bin[4]){add(1,k,k+bin[4]-1,4);k+=bin[4];}
        if(bin[5]){add(1,k,k+bin[5]-1,5);k+=bin[5];}
        if(bin[6]){add(1,k,k+bin[6]-1,6);k+=bin[6];}
        if(bin[7]){add(1,k,k+bin[7]-1,7);k+=bin[7];}
        if(bin[8]){add(1,k,k+bin[8]-1,8);k+=bin[8];}
        if(bin[9]){add(1,k,k+bin[9]-1,9);k+=bin[9];}
        if(bin[10]){add(1,k,k+bin[10]-1,10);k+=bin[10];}
        if(bin[11]){add(1,k,k+bin[11]-1,11);k+=bin[11];}
        if(bin[12]){add(1,k,k+bin[12]-1,12);k+=bin[12];}
        if(bin[13]){add(1,k,k+bin[13]-1,13);k+=bin[13];}
        if(bin[14]){add(1,k,k+bin[14]-1,14);k+=bin[14];}
        if(bin[15]){add(1,k,k+bin[15]-1,15);k+=bin[15];}
        if(bin[16]){add(1,k,k+bin[16]-1,16);k+=bin[16];}
        if(bin[17]){add(1,k,k+bin[17]-1,17);k+=bin[17];}
        if(bin[18]){add(1,k,k+bin[18]-1,18);k+=bin[18];}
        if(bin[19]){add(1,k,k+bin[19]-1,19);k+=bin[19];}
        if(bin[20]){add(1,k,k+bin[20]-1,20);k+=bin[20];}
        if(bin[21]){add(1,k,k+bin[21]-1,21);k+=bin[21];}
        if(bin[22]){add(1,k,k+bin[22]-1,22);k+=bin[22];}
        if(bin[23]){add(1,k,k+bin[23]-1,23);k+=bin[23];}
        if(bin[24]){add(1,k,k+bin[24]-1,24);k+=bin[24];}
        if(bin[25]){add(1,k,k+bin[25]-1,25);k+=bin[25];}
        }
        else
        {
            if(bin[25]){add(1,k,k+bin[25]-1,25);k+=bin[25];}
            if(bin[24]){add(1,k,k+bin[24]-1,24);k+=bin[24];}
            if(bin[23]){add(1,k,k+bin[23]-1,23);k+=bin[23];}
            if(bin[22]){add(1,k,k+bin[22]-1,22);k+=bin[22];}
            if(bin[21]){add(1,k,k+bin[21]-1,21);k+=bin[21];}
            if(bin[20]){add(1,k,k+bin[20]-1,20);k+=bin[20];}
            if(bin[19]){add(1,k,k+bin[19]-1,19);k+=bin[19];}
            if(bin[18]){add(1,k,k+bin[18]-1,18);k+=bin[18];}
            if(bin[17]){add(1,k,k+bin[17]-1,17);k+=bin[17];}
            if(bin[16]){add(1,k,k+bin[16]-1,16);k+=bin[16];}
            if(bin[15]){add(1,k,k+bin[15]-1,15);k+=bin[15];}
            if(bin[14]){add(1,k,k+bin[14]-1,14);k+=bin[14];}
            if(bin[13]){add(1,k,k+bin[13]-1,13);k+=bin[13];}
            if(bin[12]){add(1,k,k+bin[12]-1,12);k+=bin[12];}
            if(bin[11]){add(1,k,k+bin[11]-1,11);k+=bin[11];}
            if(bin[10]){add(1,k,k+bin[10]-1,10);k+=bin[10];}
            if(bin[9]){add(1,k,k+bin[9]-1,9);k+=bin[9];}
            if(bin[8]){add(1,k,k+bin[8]-1,8);k+=bin[8];}
            if(bin[7]){add(1,k,k+bin[7]-1,7);k+=bin[7];}
            if(bin[6]){add(1,k,k+bin[6]-1,6);k+=bin[6];}
            if(bin[5]){add(1,k,k+bin[5]-1,5);k+=bin[5];}
            if(bin[4]){add(1,k,k+bin[4]-1,4);k+=bin[4];}
            if(bin[3]){add(1,k,k+bin[3]-1,3);k+=bin[3];}
            if(bin[2]){add(1,k,k+bin[2]-1,2);k+=bin[2];}
            if(bin[1]){add(1,k,k+bin[1]-1,1);k+=bin[1];}
            if(bin[0]){add(1,k,k+bin[0]-1,0);k+=bin[0];}
        }
    }
    int main()
    {
        int n=rd(),m=rd();
        scanf("%s",op+1);
        build(1,1,n);
        for(int i=1;i<=m;++i)
        {
            int l=rd(),r=rd(),x=rd();
            binsort(l,r,x);
        }
        for(int i=1;i<=n;++i)
            printf("%c",(char)ask(1,i)+'a');
        puts("");
        return 0;
    }
    /*
    g++ 1.cpp -o 1
    ./1
    5 2
    cabcd
    1 3 1
    3 5 0
    */

      T2:神仙题,状态定义令人发指。。。$f[i][j]$表示前i列有j列已经放入左端点在i以前的右区间,并且i列以前已经结束的左区间以及考虑完毕的方案数。。。。。突然想找到出题人打一顿。。。稍微感性理解一下,再定义几个已知量$l[i]$代表在右端点在1到i列的区间数,$r[i]$表示左端点在1到i列的右区间数,然后就可以得到转移,我还是觉得填表好理解,$r[i]-(j-1)$为目前剩余可填的右区间数,那么就可以知道$f[i][j]=f[i-1][j-1]*(r[i]-j+1)+f[i-1][j]$就是当前列放或不放,当然还得考虑当前左区间,接下来可能比较难以理解,我也搞了好一会,首先左右区间由是用乘法原理应该很能理解,那么就剩左区间的个数了,我的理解是:由于在左区间中长区间不一定会影响短区间(可能放在短区间之外)但短区间一定会影响长区间,所以我从左往右扫就能从短到长,因此直接能求解,然而此时从右区间就是从长到短,所以我要DP求解,那么我们如何求左区间,刚刚说过短的一定影响长的(不要取笑……)我们还是已经处理完短的,那就直接排除影响找到能放的列$i-j-l[i-1]$就是此时能放的列,有$l[i]-l[i-1]$行要放,因此直接搞排列,因为是行列相交的那块,可以yy一下为啥不是组合数,$f[i][j]*=A_{i-j-l[i-1]}^{l[i]-l[i-1]}$,然后注意一下边界,不要有负数之类的,就结束了。

      

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=3020,mod=998244353;
    int l[N],r[N],f[N][N],fac[N],inv[N];
    int rd()
    {
        int s=0,w=1;
        char cc=getchar();
        while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();}
        while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar();
        return s*w;
    }
    int qpow(int a,int k)
    {
        int ans=1;
        for(;k;k>>=1,a=1ll*a*a%mod) if(k&1) ans=1ll*ans*a%mod;
        return ans;
    }
    int A(int n,int m)
    {
        if(n<0||m<0) return 0;
        if(n<m) return 0;
        if(m==0) return 1;
        return 1ll*fac[n]*inv[n-m]%mod;
    }
    int main()
    {
      //    freopen("data.in","r",stdin);
        //    freopen("data.out","w",stdout);
        int n=rd(),m=rd();fac[0]=1;
        int tm=max(n,m);
        for(int i=1;i<=tm;i++) fac[i]=1ll*fac[i-1]*i%mod;
        inv[tm]=qpow(fac[tm],mod-2);
        for(int i=tm;i;i--) inv[i-1]=1ll*inv[i]*i%mod;
        for(int i=1,x,y;i<=n;i++)
        {
            x=rd(),y=rd();
            l[x]++;r[y]++;
        }
        for(int i=1;i<=m;i++) r[i]+=r[i-1],l[i]+=l[i-1];
        f[0][0]=1;
        for(int i=1;i<=m;i++)
            for(int j=0;j<=n;j++)
            {
                if(j==0) f[i][j]=(f[i][j]+f[i-1][j])%mod;
                else
                {
                    if(r[i]-j+1>=0) f[i][j]=(f[i][j]+1ll*f[i-1][j-1]*(r[i]-j+1)%mod+f[i-1][j])%mod;
                    else f[i][j]=(f[i][j]+f[i-1][j])%mod;
                }
                f[i][j]=1ll*f[i][j]*A(i-j-l[i-1],l[i]-l[i-1])%mod;
            }
        printf("%d
    ",f[m][n]);
        return 0;
    }
    /*
    g++ 1.cpp -o 1
    ./1
    2 6
    2 4
    5 6
    */
    View Code

      T3:我不写题解,先给吴神上柱香,四句话给我搞懂了。

      

      

    //发现:对手的操作就是把目前数字左移1位,溢出位补到末尾
    //转化:对手可以把前1~i个操作都左移1位,溢出同上
    //简化:对手一共有m个数,他会选其一来异或你使你尽量小
    //问题:选出数使它被m个数中任意一个异或后的得数的最小值尽量大,最大值?方案数?
    //求解:0/1-trie,尽量避开对手的m个数。复杂度O(mn)?
    #include<cstdio>
    int n,m,c[100005],ss,ans=-1,fa,cnt,t[3000005][2];
    int ll(int p){return p&1<<n-1?p<<1^1<<n^1:p<<1;}
    void insert(int p,int pos){
        for(int i=n-1;~i;--i)
            pos=t[pos][p&1<<i?1:0]?t[pos][p&1<<i?1:0]:(t[pos][p&1<<i?1:0]=++cnt);
    }
    void dfs(int pos,int aans,int dep){
        if(dep==-1){
            if(aans==ans)fa++;
            if(aans>ans)ans=aans,fa=1;
            return;
        }
        if(t[pos][0]&&t[pos][1])dfs(t[pos][0],aans,dep-1),dfs(t[pos][1],aans,dep-1);
        else if(t[pos][0])dfs(t[pos][0],aans|1<<dep,dep-1);
        else dfs(t[pos][1],aans|1<<dep,dep-1);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;++i)scanf("%d",&c[i]),ss^=c[i];
        for(int i=0;i<=m;++i)ss^=c[i],ss^=ll(c[i]),insert(ss,0);
        dfs(0,0,n-1);
        printf("%d
    %d
    ",ans,fa);
    }
    View Code

      努力成长

  • 相关阅读:
    html5 鼠标跟随运动
    2018新年计划
    background-attachment:fixed不兼容性
    Javascript中常用方法简介
    FQ教程真实好用
    解决IE6 IE7绝对定位弹层被后面的元素遮住
    页面出现滚动条时,body里面的内容不能自动居中?
    怎么查看手机源码
    ES6入门教程---数值扩展和数组扩展
    ES6入门教程---解构赋值和字符串扩展
  • 原文地址:https://www.cnblogs.com/starsing/p/11290899.html
Copyright © 2011-2022 走看看