码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 80 (Rated for Div. 2)

时间:2020-01-15 21:27:59      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:noi   前缀和   iostream   owb   else   关系   bin   eof   分析   

A. Deadline

题解

均值,但是我第一发就wa了,也懒得管了,下一题

B. Yet Another Meme Problem

题解

\(b\) 的位数位为 \(l\) ,那么那个式子就可以写成\(ab+a+b=a*10^l+b\),稍微化简一下就很显然了,注意要特判\(b\) 全是9的情况

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int T,a,cnt;
char b[20];
int main()
{
    T=read();
    while(T--)
    {
        a=read();scanf("%s",b);
        int len=strlen(b);
        cnt=len-1;
        bool ok=0;
        for(int i=0;i<len;i++)if(b[i]!='9')ok=1;
        if(!ok)cnt++;
        cout<<(LL)cnt*(LL)a<<endl;
    }
    return 0;
}
/*

*/

C. Two Arrays

题解

I suck.OK I suck.
我就是一个憨批,这种**题硬是想成\(n^4*m\) 做法,我没救了
看起来AB有什么乱七八糟的大小关系,实际上用到A不下降,B不上升就行了,把B反过来看接在A的尾部,保证A数组不下降随随便便DP就好了。
\(f[i][j]\)表示当前为第i位,第i位为j的方案书。\(f[i][j]=\sum f[i-1][j] (j\leq i)\)
复杂度\(O(n^2m)\),其实完全可以前缀和优化少一个\(n\)的,但是能过不就得了

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int MOD=1000000007;
int n,m,dp[30][1010],ans; 
int main()
{
    n=read();m=read()*2;
    for(int i=1;i<=n;i++)dp[1][i]=1;
    for(int i=2;i<=m;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=j;k++)dp[i][j]=(dp[i][j]+dp[i-1][k])%MOD;
    for(int i=1;i<=n;i++)ans=(ans+dp[m][i])%MOD;
    printf("%d\n",ans);
    return 0;
}
/*

*/

D. Minimax Problem

题解

二分答案是肯定的,问题就在于怎么判断
把数根据index按大小分成0或1,这样就得到一坨二进制数。又因为这二进制数位数少,小于等于8位,不超过256个,直接暴力枚举即可。
(血的教训,答案一定要xjb赋一个初值,我一直wa找了半天错发现是这个)

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,a[300010][10],L,R,ans,ans1=1,ans2=1,bin[300010],has[300],pos[300];
bool judge(int index)
{
    mem(bin,0);mem(has,0);mem(pos,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(a[i][j]>=index)bin[i]=bin[i]<<1|1;
            else bin[i]<<=1;
    for(int i=1;i<=n;i++)has[bin[i]]=1,pos[bin[i]]=i;
    for(int i=0;i<(1<<m);i++)
        if(has[i])
            for(int j=i;j<(1<<m);j++)
                if(has[j] && (i|j)==(1<<m)-1)
                {
                    if(ans<index)
                    {
                        ans=index;
                        ans1=pos[i];
                        ans2=pos[j];
                    }
                    return 1;
                }
    return 0;
}
int calc(int A,int B)
{
    int res=2147483647;
    for(int i=1;i<=m;i++)res=min(res,max(a[A][i],a[B][i]));
    return res;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=read(),R=max(R,a[i][j]);
    while(R-L>1)
    {
        int mid=L+R>>1;
        if(judge(mid))L=mid;
        else R=mid;
    }
    judge(L);judge(R);
    printf("%d %d\n",ans1,ans2);
    return 0;
}

E. Messenger Simulator

题解

这题读完,第一反应:wc,好像NOIP2017day2T3,那题咋做的来着?不记得了,好像是树状数组...不管了不管了
分析每个人的最小位置,除非是把他扔到第一个去,否则他的位置不可能减少的,于是除了那些被扔到前面的哥们最小位置是1之外,其他的最小位置就是他们的出生点。
再分析每个人的最大位置,继续上一步分析,一个人什么时候能产生最大位置?要么是最后,要么是在他被扔到前面的前一瞬间,于是开个\(n+m\) 的树状数组,用树状数组来快速统计一个人前面有多少人外加移动操作,复杂度就是\(O(m*logn)\)

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=300010;
int n,m,a,pos[maxn],L[maxn],R[maxn];
struct FenwichTree
{
    int tag[maxn<<1];
    int lowbit(int x){return x&(-x);}
    void update(int x,int v){for(;x<=n+m;x+=lowbit(x))tag[x]+=v;}
    int query(int x){int res=0;for(;x;x-=lowbit(x))res+=tag[x];return res;}
}T;

int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)pos[i]=i+m,L[i]=R[i]=i,T.update(i+m,1);
    for(int i=1;i<=m;i++)
    {
        a=read();
        L[a]=1;
        R[a]=max(R[a],T.query(pos[a]));
        T.update(pos[a],-1);T.update(m-i+1,1);
        pos[a]=m-i+1; 
    }
    for(int i=1;i<=n;i++)R[i]=max(R[i],T.query(pos[i]));
    for(int i=1;i<=n;i++)printf("%d %d\n",L[i],R[i]);
    return 0;
}

废话

大晚上打cf前一定要睡觉,要不然一定会睡着

Educational Codeforces Round 80 (Rated for Div. 2)

标签:noi   前缀和   iostream   owb   else   关系   bin   eof   分析   

原文地址:https://www.cnblogs.com/FYH-SSGSS/p/12198720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!