Educational Codeforces Round 80 (Rated for Div. 2)

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前一定要睡觉,要不然一定会睡着

posted @ 2020-01-15 20:48  小飞淙的云端  阅读(169)  评论(0编辑  收藏  举报