NOI2015 迟来的测试,及时的总结

因为耽误了网络同步赛,所以在奖金一个月后进行了NOI的测试。

DAY1

T1程序自动分析

题目大意:给定一些变量相等或不等的关系,判断是否矛盾。

思路:离散化后,并查集维护一下。水水的开始。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxnode 200005
using namespace std;
struct use{
    int x1,x2,kk;
}ask[maxnode]={0};
int ai[maxnode]={0},fa[maxnode]={0};
int cmp(const use &x,const use &y){return x.kk>y.kk;}
int root(int x)
{
    if (fa[x]!=x) fa[x]=root(fa[x]);
    return fa[x];
}
int main()
{
    freopen("prog.in","r",stdin);
    freopen("prog.out","w",stdout);

    int t,i,j,n,m,siz,r1,r2;
    bool f;
    scanf("%d",&t);
    while(t)
    {
        scanf("%d",&n);ai[0]=0;
        for (i=1;i<=n;++i)
        {
            scanf("%d%d%d",&ask[i].x1,&ask[i].x2,&ask[i].kk);
            ai[++ai[0]]=ask[i].x1;
            ai[++ai[0]]=ask[i].x2;
        }
        sort(ai+1,ai+ai[0]+1);f=false;
        siz=unique(ai+1,ai+ai[0]+1)-ai-1;
        sort(ask+1,ask+n+1,cmp);
        for (i=1;i<=2*n;++i) fa[i]=i;
        for (i=1;i<=n;++i)
        {
            ask[i].x1=upper_bound(ai+1,ai+siz+1,ask[i].x1)-ai-1;
            ask[i].x2=upper_bound(ai+1,ai+siz+1,ask[i].x2)-ai-1;
            r1=root(ask[i].x1);r2=root(ask[i].x2);
            if (ask[i].kk==1)
            {
                if (r1!=r2)
                {
                   if (i%3==0) swap(r1,r2);
                   fa[r1]=r2;
                }
            }
            else
            {
                if (r1==r2)
                {
                   f=true;break;
                }
            }
        }
        if (f) printf("NO\n");
        else printf("YES\n");
        --t;
    }

    fclose(stdin);
    fclose(stdout);
}

T2软件包管理器

题目大意:给定一些软件之间的依赖关系(一棵树结构),安装时要把它到根上的都安装,卸载时要把它子树里的都卸载,求每一个操作改变的软件个数。

思路:树链剖分——链和子树,线段树维护。水水的延续。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxnode 100005
using namespace std;
char ch[10];
int tot=0,point[maxnode]={0},next[maxnode*2]={0},en[maxnode*2]={0},t[maxnode*4]={0},
    ri[maxnode]={0},delta[maxnode*4];
bool visit[maxnode]={false};
void add(int u,int v)
{
    ++tot;next[tot]=point[u];point[u]=tot;en[tot]=v;
    ++tot;next[tot]=point[v];point[v]=tot;en[tot]=u;
}
void updata(int i){t[i]=t[i*2]+t[i*2+1];}
void pushdown(int i,int l,int r)
{
    int mid;
    mid=(l+r)/2;
    if (delta[i]>=0)
    {
        delta[i*2]=delta[i];
        t[i*2]=(delta[i*2]==1 ? (mid-l+1) : 0);
        delta[i*2+1]=delta[i];
        t[i*2+1]=(delta[i*2+1]==1 ? (r-mid) : 0);
        delta[i]=delta[0];
    }
}
int task(int i,int l,int r,int ll,int rr,int kk)
{
    int mid,ans=0;
    if (ll<=l&&r<=rr) return (kk==1 ? t[i] : r-l+1-t[i]);
    pushdown(i,l,r);mid=(l+r)/2;
    if (ll<=mid) ans+=task(i*2,l,mid,ll,rr,kk);
    if (rr>mid) ans+=task(i*2+1,mid+1,r,ll,rr,kk);
    return ans;
}
void tch(int i,int l,int r,int ll,int rr,int kk)
{
    int mid;
    if (ll<=l&&r<=rr)
    {
        delta[i]=kk;t[i]=(kk==1 ? (r-l+1) : 0);return;
    }
    mid=(l+r)/2;pushdown(i,l,r);
    if (ll<=mid) tch(i*2,l,mid,ll,rr,kk);
    if (rr>mid) tch(i*2+1,mid+1,r,ll,rr,kk);
    updata(i);
}
struct lp{
    int fa[maxnode],dep[maxnode],son[maxnode],siz[maxnode],tid[maxnode],top[maxnode];
    void dfs1(int u,int f,int depth)
    {
        int i,j,maxsiz=0;
        visit[u]=true;fa[u]=f;dep[u]=depth;
        siz[u]=1;son[u]=0;
        for (i=point[u];i;i=next[i])
        {
            if (!visit[j=en[i]])
            {
                dfs1(j,u,depth+1);
                siz[u]+=siz[j];
                if (siz[j]>maxsiz)
                {
                    maxsiz=siz[j];
                    son[u]=j;
                }
            }
        }
    }
    void dfs2(int u,int anc)
    {
        int i,j;
        visit[u]=false;tid[u]=++tot;top[u]=anc;
        if (son[u]) dfs2(son[u],anc);
        for (i=point[u];i;i=next[i])
            if (visit[j=en[i]]) dfs2(j,j);
        ri[u]=tot;
    }
    int ins(int a,int b)
    {
        int ans=0;
        while(top[a]!=top[b])
        {
            if (dep[top[a]]<dep[top[b]]) swap(a,b);
            ans+=task(1,1,tot,tid[top[a]],tid[a],0);
            tch(1,1,tot,tid[top[a]],tid[a],1);
            a=fa[top[a]];
        }
        if (dep[a]>dep[b]) swap(a,b);
        ans+=task(1,1,tot,tid[a],tid[b],0);
        tch(1,1,tot,tid[a],tid[b],1);
        return ans;
    }
    int uni(int a)
    {
        int ans=0;
        ans=task(1,1,tot,tid[a],ri[a],1);
        tch(1,1,tot,tid[a],ri[a],0);
        return ans;
    }
}tree;
int main()
{
    freopen("manager.in","r",stdin);
    freopen("manager.out","w",stdout);

    int n,q,i,j;
    scanf("%d",&n);
    for (i=2;i<=n;++i)
    {
        scanf("%d",&j);add(++j,i);
    }tot=0;
    tree.dfs1(1,0,1);tree.dfs2(1,1);
    memset(delta,128,sizeof(delta));
    scanf("%d",&q);
    for (i=1;i<=q;++i)
    {
        scanf("%*c%s%d",&ch,&j);
        if (ch[0]==‘i‘)
        {
            printf("%d\n",tree.ins(1,++j));
        }
        else
        {
            printf("%d\n",tree.uni(++j));
        }
    }

    fclose(stdin);
    fclose(stdout);
}

T3寿司晚宴

题目大意:给定n-1种寿司,每个寿司编号2~n,求两个人去寿司的和谐方案的方案总数(一个方案称为和谐的当且仅当两人选择的寿司种类中两两编号互质。)

思路:测试的时候,只会暴力打表,但是还因为常数赋值时没写LL就挂了。后来问了sunshine大爷才知道正解。首先我们知道一个数n最多只有一个大于根号n的质因子,所以我们可以对一个数构成两个特征值:第1个表示大于根n的质因子,第2个表示小于根n的质因数组成(用8位2进制数表示,根号500以内的质数只有8个)。对第一个特征值排序后对这个大质因数相同的一类数一起处理(如果这个特征值为1,则一个一个的处理)。设f[i][j]表示第一个人选i,第二个人选j(i、j表示质因数的选择情况),g[k][i][j]表示第k+1个人第一个人选i第二个人选j的方案数,在每一类数做之前都用f给g数组赋值,做完这一类后f[i][j]=g[0][i][j]+g[1][i][j]-f[i][j](这里减掉的是两个都没选的情况),这里的循环要倒着来做,有点像分组背包,保证的是同一类数不可能同时出现在两边。

这道题目中处理质因数的方法很巧妙。虽然做题的时候想到了最多只有一个大于根n的质因数,但是没有灵活的用上。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxnode 1<<8
#define LL long long
using namespace std;
struct use{
    int fi,se;
}num[505]={0};
int n;
LL f[maxnode][maxnode]={0},g[2][maxnode][maxnode]={0},prime[9]={0,2,3,5,7,11,13,17,19};
int cmp(const use &x,const use &y){return x.fi<y.fi;}
int next(int i)
{
    if (num[i].fi==1) return i;
    while(num[i].fi==num[i+1].fi&&i<n) ++i;
    return i;
}
int main()
{
    freopen("dinner.in","r",stdin);
    freopen("dinner.out","w",stdout);

    int i,j,k,t,tt;LL p,ans=0;
    scanf("%d%lld",&n,&p);
    for (i=2;i<=n;++i)
    {
        k=i;
        for (j=1;j<=8;++j)
        {
            if (k%prime[j]==0)
            {
                num[i].se|=1<<(j-1);
                while(k%prime[j]==0) k/=prime[j];
            }
        }
        num[i].fi=k;
    }
    sort(num+2,num+n+1,cmp);
    f[0][0]=1;
    for (i=2;i<=n;i=tt+1)
    {
        for (j=0;j<=255;++j)
          for (k=0;k<=255;++k)
              g[0][j][k]=g[1][j][k]=f[j][k];
        tt=next(i);
        for (t=i;t<=tt;++t)
          for (j=255;j>=0;--j)
            for (k=255;k>=0;--k)
            {
                if ((j&num[t].se)==0) g[1][j][k|num[t].se]=(g[1][j][k|num[t].se]+g[1][j][k])%p;
                if ((k&num[t].se)==0) g[0][j|num[t].se][k]=(g[0][j|num[t].se][k]+g[0][j][k])%p;
            }
        for (j=0;j<=255;++j)
          for (k=0;k<=255;++k)
            f[j][k]=((g[0][j][k]+g[1][j][k]-f[j][k])%p+p)%p;
    }
    for (i=0;i<=255;++i)
      for (j=0;j<=255;++j)
        ans=(ans+f[i][j])%p;
    printf("%lld\n",ans);

    fclose(stdin);
    fclose(stdout);
}

DAY2

T1荷马史诗

题目大意:给n个字符安排一个k进制的替代码,要求一个都不是其他的前缀,同时要求最长的替代码最小。

思路:可以转化成k叉哈夫曼树,要求树高尽量小。那么像合并果子那样,用一个优先队列维护,在权值相同的时候,先合并高度小的,最后输出就行了。虽然之前没见过,但在测试时根据样例和贪心,还是可以写出来的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
struct use{
    LL val,dep;
    bool operator <(const use &x)const
    {
        return val==x.val ? dep>x.dep : val>x.val;
    }
};
priority_queue<use> que;
int main()
{
    freopen("epic.in","r",stdin);
    freopen("epic.out","w",stdout);

    int n,k,i,j; LL x,ans=0,sum,ll;
    use y;
    scanf("%d%d",&n,&k);
    for (i=1;i<=n;++i)
    {
        scanf("%I64d",&x);
        que.push((use){x,0});
    }
    j=n;
    if ((n-1)%(k-1)>0) j+=k-1-(n-1)%(k-1);
    for (i=n+1;i<=j;++i) que.push((use){0,0});
    while(j>1)
    {
        sum=ll=0;
        for (i=1;i<=k;++i)
        {
            y=que.top();que.pop();
            ans+=y.val;sum+=y.val;
            ll=max(ll,y.dep);
        }
        j-=k-1;que.push((use){sum,ll+1});
    }
    y=que.top();
    printf("%I64d\n%I64d\n",ans,y.dep);

    fclose(stdin);
    fclose(stdout);
}

T2品酒大会

题目大意:给定一个字符串,求lcp(i,j)>=l(l=0~n-1)的对数和val[i]*val[j]的最大值。

思路:后缀数组的题目。跟差异很像,处理出sa,rank,height数组后分治处理一下就可以了。

测试时其他有同学按height从大到小排序,然后用并查集做,很神的做法啊。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#define maxnode 300005
#define inf 0x7fffffffffffffffLL
#define LL long long
using namespace std;
struct use{
    int minn,minp;
}tree[maxnode*4]={0};
struct uu{
    LL maxn,minn;
}sta;
int sa[maxnode]={0},rank[maxnode]={0},c[maxnode]={0},t1[maxnode]={0},t2[maxnode]={0},
    height[maxnode]={0},n,m;
char ss[maxnode];
LL ans[2][maxnode]={0},val[maxnode]={0};
bool cmp(int *y,int a,int b,int k)
{
    int a2,b2;
    a2= a+k>=n ? -1 : y[a+k];
    b2= b+k>=n ? -1 : y[b+k];
    a=y[a];b=y[b];
    return a==b&&a2==b2;
}
void build()
{
    int i,k,p,*x=t1,*y=t2;
    for (i=0;i<m;++i) c[i]=0;
    for (i=0;i<n;++i) ++c[x[i]=(ss[i]-‘a‘)];
    for (i=1;i<m;++i) c[i]+=c[i-1];
    for (i=n-1;i>=0;--i) sa[--c[x[i]]]=i;
    for (k=1;k<=n;k<<=1)
    {
        p=0;
        for (i=n-k;i<n;++i) y[p++]=i;
        for (i=0;i<n;++i) if (sa[i]>=k) y[p++]=sa[i]-k;
        for (i=0;i<m;++i) c[i]=0;
        for (i=0;i<n;++i) ++c[x[y[i]]];
        for (i=1;i<m;++i) c[i]+=c[i-1];
        for (i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i];
        swap(x,y);m=1;x[sa[0]]=0;
        for (i=1;i<n;++i) x[sa[i]]=cmp(y,sa[i],sa[i-1],k) ? m-1 : m++;
        if (m>=n) break;
    }
}
void pre()
{
    int i,j,k=0;
    for (i=0;i<n;++i) rank[sa[i]]=i;
    for (i=0;i<n;++i)
    {
        if (!rank[i]) continue;
        if (k) --k; j=sa[rank[i]-1];
        while(ss[i+k]==ss[j+k]) ++k;
        height[rank[i]]=k;
    }
}
use updata(use x1,use x2)
{
    if (x1.minn<=x2.minn) return x1;
    else return x2;
}
uu updata2(uu x1,uu x2)
{
    uu x3;
    x3.minn=min(x1.minn,x2.minn);
    x3.maxn=max(x1.maxn,x2.maxn);
    return x3;
}
void buildt(int i,int l,int r)
{
    int mid;
    if (l==r)
    {
        tree[i].minn=height[l];tree[i].minp=l;return;
    }
    mid=(l+r)/2;
    buildt(i*2,l,mid);buildt(i*2+1,mid+1,r);
    tree[i]=updata(tree[i*2],tree[i*2+1]);
}
use task(int i,int l,int r,int ll,int rr)
{
    int mid; use x1,x2;
    if (ll<=l&&r<=rr) return tree[i];
    x1.minn=x2.minn=x1.minp=x2.minp=2100000000LL;
    mid=(l+r)/2;
    if (ll<=mid) x1=task(i*2,l,mid,ll,rr);
    if (rr>mid) x2=task(i*2+1,mid+1,r,ll,rr);
    return updata(x1,x2);
}
uu work(int l,int r)
{
    if (l>=r)
    {
       if (l==r) return (uu){val[sa[l]],val[sa[l]]};
       else return sta;
    }
    use x; x=task(1,0,n-1,l+1,r);
    ans[0][x.minn]+=(LL)(x.minp-l)*(LL)(r-x.minp+1);
    uu x1,x2;
    x1=work(l,x.minp-1);x2=work(x.minp,r);
    ans[1][x.minn]=max(ans[1][x.minn],max(x1.maxn*x2.maxn,max(x1.minn*x2.minn,
                   max(x1.maxn*x2.minn,x1.minn*x2.maxn))));
    return updata2(x1,x2);
}
int main()
{
    freopen("savour.in","r",stdin);
    freopen("savour.out","w",stdout);

    int i,j;
    scanf("%d",&n);m=26;
    while(1)
    {
        ss[0]=getchar();
        if (ss[0]>=‘a‘&&ss[0]<=‘z‘) break;
    }
    for (i=1;i<n;++i) ss[i]=getchar();
    for (i=0;i<n;++i) scanf("%I64d",&val[i]);
    build();pre();buildt(1,0,n-1);
    memset(ans[1],128,sizeof(ans[1]));
    sta.maxn=ans[1][maxnode-1];sta.minn=inf;work(0,n-1);
    for (i=n-1;i>=0;--i)
    {
        ans[0][i]+=ans[0][i+1];
        ans[1][i]=max(ans[1][i],ans[1][i+1]);
    }
    for (i=0;i<n;++i)
      printf("%I64d %I64d\n",ans[0][i],(ans[0][i]==0 ? 0 : ans[1][i]));

    fclose(stdin);
    fclose(stdout);
}

时间: 2024-10-02 08:15:16

NOI2015 迟来的测试,及时的总结的相关文章

普及一下中小企业项目上线的一般流程

在公司从事运维工作期间,发现了一些更新上线项目发布的问题: 1,程序中写有大量的接口调用使用的是ip地址. 2,程序中的垃圾代码很多,用我的话说程序不干净,很明显是因为交接造成的. 3,生产环境更新的备份文件压缩文件到处乱放 tomcat等的日志有分割但是没有定期清理,高达上G.配置文件  写的一沓混乱. 4,运维人员离职居然没有交接文档,更没有生产环境的维护文档. 更甚的是我这个倒霉蛋居然来了都没人给个口头交接,只是口头仅此而已,没有. 5,更新上线没有提前通知规定,没正式流程 都要过年了居然

tcp/ip体系-转载

如果还想在测试这条路上继续走下去的话,那么下面这些东西就是我们必须去掌握的,至少你还不想止步于简单的黑盒测试--其实,一直想去接触Linux下的应用测试,这样能学到东西会很多,而且会非常的受用.之前听小布老师讲,如果你想在IT技术上长期发展下去,那么你就大胆拥抱Linux吧,因为在这里你能学到东西远胜过于你在Windows平台下学到的东西,而其中最经典的一段话就是:如果你一直跟随微软的技术,那么终究会被拖死,因为微软的技术一直在变化,而你却需要不断的去学习他的东西.而Linux不一样,它更多的是

ARMLinux下Alignment trap的一些测试 【转自 李迟的专栏 CSDN http://blog.csdn.net/subfate/article/details/7847356

项目中有时会遇到字节对齐的问题,英文为“Alignment trap”,如果直译,意思为“对齐陷阱”,不过这个说法不太好理解,还是直接用英文来表达. ARM平台下一般是4字节对齐,可以参考文后的给出的文章链接.此处不细说.后面提及“字节对齐” 下面的例子使用了几种重现Alignment trap的方法,例子1是将char*指针直接转换成int*指针,经测试,未发现有字节对齐的问题.例子2和例子3相似,主要是结构体中的字段没有进行对齐(或者访问的地址没有4字节对齐).例子4是直接访问了没有字节对齐

迟来的2016-2017年测试职业总结

时间不留情面的匀速向前,而我的生活轨迹,有时太慢,跟不上时间的速度,比如:过完年回来,每次清晨都是挣扎着起床:有时太快,快的仿佛自己已经不在这个地球,比如:偶尔晚间的梦里.不管我怎么过,时间还在那行走,一年很快就过了,回眸间,仿佛上一个春节就在昨天,用时间的步伐来计算,干测试已经2个年头多了,加上实习的话. 这一年我干了什么呢!说实话,感觉是:遗憾多,收获少. 2015年11月进入现在的公司,开始接手风控平台的测试,物业费业务的测试,电子账单业务的测试等等等,........ 从2016年开始说

Qihoo360 Atlas MySQL Proxy测试小结

Qihoo360将他们改造后的MySQL Proxy项目开源了,至于为什么起名Atlas就不清楚了,项目地址:https://github.com/Qihoo360/Atlas.我2008年曾测试过官方版本的MySQL Proxy,主要是看中其连接池以及读写分离功能,不过当时的版本效率实在太差,后面就没再关注了.这几天对Qihoo360 Atlas做了下测试,下面是测试结果. 环境准备 服务器端: 测试机 DELL PE R710 CPU E5620  @ 2.40GHz(4 core, 8 t

「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集

时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话题,结识业界朋友. 「Mobile Testing Summit China 2016」中国移动互联网测试大会 大会定位:专注移动互联网测试技术的分享会,关注移动互联网质量的有志之士的集会. 大会主旨:秉承着务实.能落地.有深度.高质量.重分享的原则与广大测试工程师做最新最实用的分享与交流,以推广新

web应用程序测试方法和测试技术详述

1.界面测试 现在一般人都有使用浏览器浏览网页的经历,用户虽然不是专业人员但是对界面效果的印象是很重要的.如果你注重这方面的测试,那么验证应用程序是否易于使用就非常重要了.很多人认为这是测试中最不重要的部分,但是恰恰相反界面对不懂技术的客户来说那相当关键,慢慢体会你会明白的. 方法上可以根据设计文档,如果够专业的话可以专业美工人员,来确定整体风格页面风格,然后根据这个可以页面人员可以生成静态的HTML,CSS等甚至生成几套不用的方案来讨论,或者交给客户评审,最后形成统一的风格的页面/框架.注意不

十天冲刺任务迟真真

4月29日  上网搜集有关jsp文件上传于下载的资料4月30日  观看视频教程5月1日  设计文件的上传功能,可以上传.doc..txt pdf rip等文件5月2日  设置file类表单5月3日   连接数据库,实现上传文件到服务器5月4日   设计文件的下载功能5月5日    注册servlet5月6日    实现下载功能,Jsp内置对象response调用方法getOutputStream()可以获          取一个指向客户的输出流,服务器将文件写入这个流,然后可下载此文件5月7日

Uoj #131. 【NOI2015】品酒大会 后缀数组,并查集

#131. [NOI2015]品酒大会 统计 描述 提交 自定义测试 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 nn 杯鸡尾酒.这 nn 杯鸡尾酒排成一行,其中第 ii 杯酒 (1≤i≤n1in) 被贴上了一个标签 sisi,每个标签都是 2626 个小写英文字母之一.设 Str(l,r)Strlr 表示第 ll 杯酒到第 rr 杯酒的