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] (jleq 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
",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
",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
",L[i],R[i]);
return 0;
}
废话
大晚上打cf前一定要睡觉,要不然一定会睡着