Codeforces Round #442 (Div. 2)
第一次打cf,感觉很有意思。
llj大佬A了三题的时候还没有看到a题在讲什么,谷歌翻译把 a 翻译成了1,愉快被坑。
写了的都是些简单的签到题,写得太慢还掉了rating,,,,,
a.模拟
站一个点往两边小的那个跑。
//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
int n,a,b,c,now,ans,l[10],r[10],ll[10],rr[10];
int main()
{
cin>>n>>a>>b>>c;
l[1]=2; r[1]=3; ll[1]=a; rr[1]=b;
l[2]=3; r[2]=1; ll[2]=c; rr[2]=a;
l[3]=1; r[3]=2; ll[3]=b; rr[3]=c;
int now=1,cnt=0;
while(cnt<=n) {
cnt++;
if(cnt>=n) break;
if(ll[now]<=rr[now]) {ans+=ll[now]; now=l[now]; }
else {ans+=rr[now]; now=r[now]; }
}
cout<<ans<<endl;
return 0;
}
b.发现mod b答案相同的点是一起的。当一坨长度够了就break。
//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
inline int read() {
int ret=0,f=1; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
return ret*f;
}
int n,k,m,a[maxn],pos[maxn],cnt[maxn],pr[maxn],fl,now;
int main()
{
n=read(); k=read(); m=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) {
now=a[i]%m;
if(pos[now]) pr[i]=pos[now];
cnt[now]++;
pos[now]=i;
if(cnt[now]==k) {now=i; fl=1; break;}
}
if(!fl) printf("No\n");
else {
printf("Yes\n");
printf("%d ",a[now]);
while(pr[now]) {
printf("%d ",a[pr[now]]);
now=pr[now];
}
printf("\n");
}
return 0;
}
c.发现最大不过能加9*9=81,枚举从max(0,n-81) ~n,判断可行即可。
注意要升序输出,WA了两发。。。。
//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
int n,ans[100];
int main()
{
scanf("%d",&n);
for(int i=max(1,n-81);i<=n;i++) {
int tp=i,tpp=i;
while(tp) {
tpp+=tp%10;
tp/=10;
}
if(tpp==n) ans[++ans[0]]=i;
}
printf("%d\n",ans[0]);
for(int i=1;i<=ans[0];i++)
printf("%d ",ans[i]);
printf("\n");
return 0;
}
d.转换模型成求逆序对最多的人的逆序对的个数。
一定是最后面一个人。随便怎么模拟乱搞一下就可以了。
//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
const int maxn=300005;
int n,a[maxn],x,ans,now,as[maxn];
int main()
{
scanf("%d",&n);
as[0]=1;
for(int i=1;i<=n;i++) {
scanf("%d",&x);
a[x]=1;
if(x!=n&&a[x+1]!=1) ans++;
else {
if(x==n) {
now=n; a[now]=1;
while(a[now-1]==1) {now--; ans--; }
}
else {
a[x]=1;
if(now!=x+1) ans++;
else {
now=x;
while(now>=2&&a[now-1]==1) {
now--;
ans--;
}
}
}
}
as[i]=ans+1;
}
for(int i=0;i<=n;i++) printf("%d ",as[i]);
printf("\n");
return 0;
}
e.听说是2_sat;
不会。
f.
llj大佬给我讲得好像很有道理的样子,结果WA了。
//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
const int maxn=200005;
using namespace std;
typedef long long LL;
LL ans;
int n,a[maxn],l[maxn],r[maxn],q[maxn],h[maxn],ll[50],rr[50],que[maxn],ql=1,qr;
void read(int &x) {
int ret=0,f=1; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
x=ret*f;
}
int main()
{
read(n);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) {
while(ql<=qr&&a[i]>=a[que[qr]]) {qr--;}
if(ql<=qr) l[i]=que[qr]+1;
else l[i]=1;
que[++qr]=i;
for(int j=1;j<=30;j++) {
if(a[i]&(1<<j-1)) ll[j]=i;
else if(ll[j]&&(!q[i]||q[i]<ll[j])) q[i]=ll[j];
}
}
ql=1; qr=0;
for(int i=n;i>=1;i--) {
while(ql<=qr&&a[i]>=a[que[qr]]) {qr--;}
if(ql<=qr) r[i]=que[qr]-1;
else r[i]=n;
que[++qr]=i;
for(int j=1;j<=30;j++) {
if(a[i]&(1<<j-1)) rr[j]=i;
else if(rr[j]&&(!h[i]||h[i]>rr[j])) h[i]=rr[j];
}
}
for(int i=1;i<=n;i++) {
if(q[i]&&h[i])
ans+=((LL)(i-l[i]+1)*(r[i]-i+1)-(LL)(i-q[i])*(h[i]-i));
}
printf("%I64d\n",ans);
return 0;
}