A:开场就读错题。读对了之后也没啥好说的。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,a[N],cnt[N],tot;
vector<int> pos[N];
ll ans;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
m=read(),n=read();
for (int i=1;i<=n;i++) a[i]=read(),pos[a[i]].push_back(i);
for (int i=1;i<=m;i++)
{
if (i>1)
{
if (pos[i].empty()) ans++;
else
{
int x=pos[i][0];
if (pos[i-1].empty()||pos[i-1][pos[i-1].size()-1]<x) ans++;
}
}
if (pos[i].empty()) ans++;
if (i<m)
{
if (pos[i].empty()) ans++;
else
{
int x=pos[i][0];
if (pos[i+1].empty()||pos[i+1][pos[i+1].size()-1]<x) ans++;
}
}
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}
B:swap(1B,1D)。花了1h+仍然没有比暴力更好的做法,于是信仰交了暴力神tmpp了,最后居然似乎是因为用了map或者randomshuffle而fst,更加纯粹的暴力反而过了。无法想到的结论是,如果有解,一定存在某个解k是n的因子。考虑反证,如果只存在不是n因子的k的话,选择某条边一直往后跳k,最后会需要所有与其差为gcd(n,k)的边都存在,于是如果k合法,gcd(n,k)也一定合法。
upd:这似乎是一件足够显然的事,可能太晚了脑子不好。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 100010
#define M 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,t;
map<int,int> f[N];
struct data{int x,y;
}a[M<<1];
int dis(int x,int y){return x<y?y-x:n-x+y;}
int nxt(int x,int y){x+=y;if (x>n) x-=n;return x;}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();srand(time(0));
for (int i=1;i<=m;i++)
{
a[i].x=read(),a[i].y=read();
f[a[i].x][a[i].y]=f[a[i].y][a[i].x]=1;
}
random_shuffle(a+1,a+m+1);
for (int i=1;i<n;i++)
if (n%i==0)
{
bool flag=1;
for (int j=1;j<=m;j++)
if (!f[nxt(a[j].x,i)][nxt(a[j].y,i)]) {flag=0;break;}
if (flag) {cout<<"Yes";return 0;}
}
cout<<"No";
return 0;
//NOTICE LONG LONG!!!!!
}
C:场上最后5min的时候猜了一个一个石子的堆数<=n/2时Alice赢,wa4。然后正解就是最少石子的堆数<=n/2时Alice赢。注意到有人被迫拿完一堆石子就输了,进一步有人被迫减少所有石子中的最小值就输了,因为另一方此时一定可以不减小最小值。而是否被迫就取决于上面的条件。在这个条件下必胜态一定可以转移到必败态,必败态只能转移到必胜态。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 55
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=1;i<=n;i++) a[i]=read();
int x=100;for (int i=1;i<=n;i++) x=min(x,a[i]);
int cnt=0;
for (int i=1;i<=n;i++) if (a[i]==x) cnt++;
if (cnt<=n/2) cout<<"Alice";else cout<<"Bob";
return 0;
//NOTICE LONG LONG!!!!!
}
D:要是我放弃希望死磕B大约能掉回紫()枚举b串长度,a串每一位和b串每一位都视作一个点,并查集将要求数字相同的位合并,要求不同的位连边,并且对于某些位的强制设为1/0,也当做两个点加入这张图中进行合并。然后跑一个二分图染色,不是二分图显然没有贡献,跑完看一下1的颜色和0的颜色是否相同,若相同也显然没有贡献。然后贡献就是2不含01的连通块个数。丝毫看不出来为什么放在D。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 4010
#define P 998244353
#define ida(x) (x)
#define idb(x) (n+(x))
#define S0 (n+m+1)
#define S1 (n+m+2)
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
char s[N];
int n,t,T,fa[N],a[N],p[N],color[N];
bool flag;
ll ans;
struct data{int x,y;}e[N];
struct data2{int to,nxt;
}edge[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void merge(int x,int y){fa[find(x)]=find(y);}
int ksm(int a,int k)
{
int s=1;
for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
return s;
}
void addedge(int x,int y){T++;edge[T].to=y,edge[T].nxt=p[x],p[x]=T;}
void paint(int k,int c)
{
color[k]=c;
for (int i=p[k];i;i=edge[i].nxt)
if (color[edge[i].to]==-1) paint(edge[i].to,c^1);
else if (color[edge[i].to]==c) flag=0;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
#endif
scanf("%s",s+1);
n=strlen(s+1);reverse(s+1,s+n+1);
for (int m=n-1;m>=1;m--)
{
for (int i=1;i<=n+m+2;i++) fa[i]=i;t=0;T=0;
for (int i=1;i<=n;i++) merge(ida(i),ida(n-i+1));
for (int i=1;i<=m;i++) merge(idb(i),idb(m-i+1));
for (int i=n;i>m;i--)
{
if (s[i]=='0') merge(ida(i),S0);
if (s[i]=='1') merge(ida(i),S1);
}
merge(idb(m),S1);
for (int i=m;i>=1;i--)
{
if (s[i]=='0') merge(ida(i),idb(i));
if (s[i]=='1') t++,e[t].x=ida(i),e[t].y=idb(i);
}
memset(p,0,sizeof(p));
for (int i=1;i<=t;i++)
{
addedge(find(e[i].x),find(e[i].y));
addedge(find(e[i].y),find(e[i].x));
}
memset(color,255,sizeof(color));
flag=1;
for (int i=1;i<=n+m+2;i++) if (color[i]==-1) paint(i,0);
if (!flag) continue;
int u=color[find(S0)],v=color[find(S1)];
for (int i=1;i<=t;i++) merge(e[i].x,e[i].y);
if (find(S0)==find(S1)&&u==v) continue;
int cnt=0;
for (int i=1;i<=n+m+2;i++)
if (find(i)==i) cnt++;
cnt--;if (find(S0)!=find(S1)) cnt--;
ans=(ans+ksm(2,cnt))%P;
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}
E:待会补.jpg怎么是个交互算了不补了。
结论题乃一生之敌。昨天晚上agc也被两个博弈卡死最后都没敢交题。
想起来这位上次的比赛也是D比EFGH都难(当然也是结论题),下次得格外小心。不对退役前肯定没有了担心个啥
You should stop creating problems
result:rank 287 rating -81 小号刚好变成小小号惹。