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

      这次考试就不骂自己了,毕竟骂了也没用。T1是水题。。用map手卡30分,我tm。。。。然后以为这就结束了,然后去改T2,T2WA40,我写的主席树但是修改是自己yy的,以为就是错了,然后把离散化去了,WA80?????!!!然后加上WA40。。。。然后我好好研究了一下,突然想到它可能询问从没出现过的颜色,然后判了一句,A了。。。。因为没出现过就是0,主席树查不出来。。。T3考场上吃屎一会再说。

      T1:这是一道规律题,找的话其实打个父亲表,看一下就能知道,一个数的父亲就是这个数之前减去离他最近的斐波数,我们又可以知道这个斐波数增长飞快,见过通项的都知道,这玩意是指数级的,所以就可以打个表知道大概60多个就到13位了,找父亲log60,抬lca是60,一次操作就是常数,m次绝对可以接受,结果忘了之前搞得一个map没删,就死了30分。

      

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    long long f[10000];    
    long long rd()
    {
        long long 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;
    }
    long long fa(long long x)
    {
        long long id=lower_bound(f+1,f+64,x)-f-1;
        return x-f[id];
    }
    long long getdep(long long tmp)
    {
        long long ans=0,x=tmp;
        while(x!=1)
        {
            ++ans;
            x=fa(x);
        }
        return ans;
    }
    long long lca(long long a,long long b)
    {
        int depa=getdep(a),depb=getdep(b);
        if(depa<depb) swap(a,b),swap(depa,depb);
        while(depa>depb) a=fa(a),depa--;
        if(a==b) return a;
        while(fa(a)!=fa(b)) a=fa(a),b=fa(b);
        return fa(a);
    }
    int main()
    {
        f[0]=1;f[1]=1;
        for(int i=2;i<=63;i++)
        {
            f[i]=f[i-1]+f[i-2];
        }
        int m=rd();
        for(int i=1;i<=m;i++)
        {
            long long a=rd(),b=rd();
            if(a==1||b==1)
            {
                puts("1");
                continue;
            }
            printf("%lld
    ",lca(a,b));
        }
        return 0;
    }
    /*
    g++ 1.cpp -o 1
    ./1
    5
    1 1
    2 3
    5 7
    7 13
    4 12
    */
    View Code

      T2:手动修改的主席树,因为这个修改不是修改,是交换,这很重要,那这样后面的主席树都不用改,只改一颗就行了,然后就可以性感询问,在线回复了。还是一样,可持久化烧内存,内存开够就没了。主席树码量极小

      

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=300050;
    int rt[N],a[N],p[N],tt=0,cnt=0;
    struct tree{int lc,rc,w;}tr[50000020];
    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 insert(int &x,int l,int r,int p,int va)
    {
        tr[++tt]=tr[x];x=tt;
        if(l==r)
        {
            tr[x].w+=va;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid) insert(tr[x].lc,l,mid,p,va);
        else insert(tr[x].rc,mid+1,r,p,va);
    }
    int query(int x,int l,int r,int p)
    {
        if(l==r)return tr[x].w;
        int mid=(l+r)>>1;
        if(p<=mid)return query(tr[x].lc,l,mid,p);
        else return query(tr[x].rc,mid+1,r,p);
    }
    int main()
    {
        int n=rd(),m=rd();
        for(int i=1;i<=n;i++)
        {
            a[i]=rd();
            if(!p[a[i]]) p[a[i]]=++cnt;
        }
        for(int i=1;i<=n;i++)
        {
            rt[i]=rt[i-1];
            insert(rt[i],1,cnt,p[a[i]],1);
        }
        while(m--)
        {
            int op=rd();
            if(op==1)
            {
                int l=rd(),r=rd(),c=rd();
                if(!p[c]) puts("0");
                else printf("%d
    ",query(rt[r],1,cnt,p[c])-query(rt[l-1],1,cnt,p[c]));
            }
            else 
            {
                int l=rd();
                insert(rt[l],1,cnt,p[a[l]],-1);
                insert(rt[l],1,cnt,p[a[l+1]],1);
                swap(a[l],a[l+1]);
            }
        }
    }
    /*
    g++ 2.cpp -o 2
    ./2
    10 9
    1 2 3 4 5 6 1 2 3 4
    1 1 3 3
    1 4 6 3
    2 3
    1 1 3 3
    1 4 6 3
    1 1 10 4
    1 1 10 3
    1 1 10 2
    1 1 10 1
    */
    View Code

      T3:首先这个题不是DP,倒着扫一遍,贪心找最长的合法区间,然后既能保证最少,也能保证最小。然后k=1的时候好搞,随便搞搞就行了,k=2的时候用二分图来做,我考试的时候鬼畜没看到k只能等于1或2,然后就开始yy,发现如果在一张图上如果把非敌对关系建图(反图)的话,在只有双联通分量里的点才能分成一个小组,于是我就开始了愉快的tarjan。。。。这题k=2的时候二分图可以跑过,我们就可以通过二分图判定,来判断这一堆猫啊不兔子是否能分两组,这个题的打法没怎么见过,不是dp只能瞎打。自己yy了一个调了一下午。

      另外:亲测告诉各位卡常大师,sqrt函数我估计是$O(2^{n})$的,慢到没分数,直接打表比sqrt快3000ms

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    //const int L=1<<20|1;
    //char buffer[L],*S,*T;
    //#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
    using namespace std;
    const int N=3000050;
    bool v[N],ch[N];
    int c[N],s[N],a[N],tt,qn,tot,fr[N*2];
    struct node{int fr,to,pr;}mo[N*2];
    void add(int x,int y)
    {
        mo[++tt].fr=x;
        mo[tt].to=y;
        mo[tt].pr=fr[x];
        fr[x]=tt;
    }
    bool dfs(const register int x,const register int cl)
    {
        c[x]=cl;
        //cout<<x<<endl;
        for(int i=fr[x];i;i=mo[i].pr)
        {
            const register int to=mo[i].to;
            //cout<<to<<" "<<cl<<endl;
            if(c[to]==cl)return false;
            if(c[to]==0&&!dfs(to,-cl))return false;
        }
        return true;
    }
    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 main()
    {
        int bm=0;
        int n=rd(),K=rd();
        for(int i=1;i<=512;i++) ch[i*i]=1;
        for(int i=1;i<=n;i++)
            a[i]=rd(),bm=max(bm,a[i]);
        if(K==1)
        {
            for(int i=n;i;)
            {
                bool flag=1;
                int j=i;
                for(;j;j--)
                {
                    for(int k=1;k<=512;k++)
                    {
                        if(v[k*k-a[j]]){flag=0;break;}
                    }
                    if(flag==0) break;
                    v[a[j]]=1;
                }
                for(int k=j;k<=i;k++) v[a[k]]=0;
                i=j;
                if(j!=0) s[++tot]=j;
            }
            printf("%d
    ",tot+1);
            for(int i=tot;i;i--) printf("%d ",s[i]);
            puts("");
            return 0;
        }
        else
        {
            for(int i=n;i;)
            {
                bool flag=1;
                register int j=i;
                for(;j;j--)
                {
                    for(int k=j+1;k<=i;k++)if(ch[a[j]+a[k]])add(j,k),add(k,j);
                    for(int k=j;k<=i;k++)c[k]=0;
                    if(!dfs(j,1))break;
                }
                for(int k=j;k<=i;k++)fr[k]=0;
                i=j;tt=0;
                s[++tot]=j;
            }
            printf("%d
    ",tot);
            for(int i=tot-1;i;i--) printf("%d ",s[i]);
            puts("");
            return 0;
        }
    }
    /*
    g++ 3.cpp -o 3
    ./3
    5 2
    1 3 15 10 6
    */
    View Code

     

  • 相关阅读:
    Bootstrap 2.2.2 的新特性
    Apache POI 3.9 发布,性能显著提升
    SQL Relay 0.48 发布,数据库中继器
    ProjectForge 4.2.0 发布,项目管理系统
    红帽企业 Linux 发布 6.4 Beta 版本
    红薯 快速的 MySQL 本地和远程密码破解
    MariaDB 宣布成立基金会
    Percona XtraBackup 2.0.4 发布
    Rocks 6.1 发布,光盘机群解决方案
    精通Servlet研究,HttpServlet的实现追究
  • 原文地址:https://www.cnblogs.com/starsing/p/11296349.html
Copyright © 2011-2022 走看看