前言
145(175?)pts
100+45+0(30?)
rnk11(8?)
之所以有括号是因为T3莫名其妙的TLE了?
考后我一模一样的码再交一遍30分就到手了…
应该不是我的问题吧,今天考试的机子确实有些诡异,一开始评测乱七八糟的qwq。
感觉整体发挥没有大的失误。
但是排名就是不太好…
感觉今天题也不算太简单阿qwq
可能只有我这么认为吧
如果一场考试摆烂的时间太长,似乎几乎很难拿到太好的排名…
就像这次,最后10:45左右开始就没啥事干了,一直在检查代码…
中间还和lyn学长聊了回天
题目解析
字符变换(character)
由于操作1,只要字母个数相同,就可以任意互相转化,属于同一个“等价类”,其方案数也可以用不可重排列求得(__int128
天下第一!)
当 n=30 时,等价类个数是 5500 左右(以后称等价类个数为 www)
然后题目给出的操作二的转化就是在不同的等价类之间转移,暴力加边复杂度是 O(wm)O(wm)O(wm) 的,可以接受。
然后跑个tarjan缩点,再跑个带权最长路径的简单 dp 即可。
这个题确实没有太大的难度,思路整体是比较顺的。
格子染色(color)
魔法题目。
拿到45分足矣。
本题的正解做法就是观察sg函数表找规律,离大谱。
尤其 k=1 的sg,规律是:“当n>=52时,存在一个大小为 34 的周期”。
这个甚么神人能看出来啊…
其实你要告诉我是类似的东西也未见得看不出来,但是实在不会想到会是这种鬼畜的规律…
k=2的 sg 性质的推导可以使用类似于数学归纳法的东西(然而打表还是很好用),其实这个规律比那个鬼畜东西强多了,但是由于 k=1 我都没看出来规律,就没有打 k=2 的表,大损失。
以线覆圆(circle)
很妙的一个状压 dp。
非离散的期望感觉根本没法做的样子…
关键是:一个方案真正关心的只有其整数部分的绝对大小和小数部分的相对大小关系。
所以可以暴力枚举小数部分的大小,然后就变成了类似于 n∗mn*mn∗m 个点上状压。
然鹅由于某些奥秘重重的问题,我就是过不去。
最后写的n=2点30分被ybt机子吃了??
赛后再交一遍一样的码就拿到了30分…
我谔谔。
代码
T1
#include<bits/stdc++.h>
using namespace std;
#define ll __int128
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
void write(ll x){if(x>9) write(x/10);putchar('0'+x%10);
}
const int N=5500;int n,m;int num[N][5],tot;
ll jc[35],val[N<<1];int id[31][31][31][31];
int x[5];
void print(int x){printf("(%d %d %d %d) ",num[x][1],num[x][2],num[x][3],num[x][4]);
}
void dfs(int k,int lft){if(k==4){x[k]=lft;++tot;for(int i=1;i<=4;i++) num[tot][i]=x[i];val[tot]=jc[n]/jc[x[1]]/jc[x[2]]/jc[x[3]]/jc[x[4]];id[x[1]][x[2]][x[3]][x[4]]=tot;//printf("%d: ",tot);print(tot);puts("");return;}for(int i=0;i<=lft;i++){x[k]=i;dfs(k+1,lft-i);}return;
}
struct node{int to,nxt;
}p[N*N];
int fi[N<<1],cnt;
inline void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
}
int s[5],t[5];
int now[5];
char s1[N],s2[N];
int dfn[N<<1],low[N<<1],zhan[N<<1],col[N<<1],top,tim;
void tarjan(int x){dfn[x]=low[x]=++tim;zhan[++top]=x;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(!dfn[to]){tarjan(to);low[x]=min(low[x],low[to]);}else if(!col[to]) low[x]=min(low[x],dfn[to]);}if(low[x]==dfn[x]){col[x]=++tot;val[tot]=val[x];while(zhan[top]!=x){int now=zhan[top--];col[now]=tot;val[tot]+=val[now];}top--;}
}
ll dp[N<<1];
ll find(int x){if(dp[x]) return dp[x];dp[x]=val[x];for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;dp[x]=max(dp[x],find(to)+val[x]);}return dp[x];
}signed main(){freopen("character.in","r",stdin);freopen("character.out","w",stdout);//printf("%d\n",sizeof(p)/1024/1024);//printf("%d\n",sizeof(e)/1024/1024);//printf("%d\n",sizeof(id)/1024/1024);//printf("%d\n",sizeof(val)/1024/1024);memset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();ok;jc[0]=1;for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i;dfs(1,n);//printf("tot=%d\n",tot);for(int tim=1;tim<=m;tim++){memset(s,0,sizeof(s));memset(t,0,sizeof(t));scanf(" %s %s",s1+1,s2+1);int len=strlen(s1+1);if(len>n) continue;for(int i=1;i<=len;i++) s[s1[i]-'A'+1]++;for(int i=1;i<=len;i++) t[s2[i]-'A'+1]++;//printf("\ntim=%d\n",tim);//for(int i=1;i<=4;i++) printf("%d ",s[i]);puts("");//for(int i=1;i<=4;i++) printf("%d ",t[i]);puts("");for(int i=1;i<=tot;i++){int flag(0);for(int j=1;j<=4;j++){now[j]=num[i][j]-s[j];if(now[j]<0) flag=1;}if(flag) continue;for(int j=1;j<=4;j++) now[j]+=t[j];int to=id[now[1]][now[2]][now[3]][now[4]];addline(i,to);//printf("%d->%d\n",i,to);}}n=tot;for(int i=1;i<=n;i++){if(!dfn[i]) tarjan(i);}for(int i=1;i<=n;i++){for(int j=fi[i];~j;j=p[j].nxt){int to=p[j].to;if(col[i]==col[to]) continue;addline(col[i],col[to]);}}ll ans(0);for(int i=n+1;i<=tot;i++) ans=max(ans,find(i));write(ans);return 0;
}
/*
*/
T2
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=1e5+100;int n,m;
int a[N];struct AA{int sg[N];int bac[N],clo;int find(int x){if(x>54){x-=54;x%=34;x+=54;}if(x<=2) return 0;if(sg[x]!=-1) return sg[x];for(int i=2;i<=x-1;i++){find(i-1);find(x-i);}++clo;for(int i=2;i<=x-1;i++){bac[find(i-1)^find(x-i)]=clo;}sg[x]=0;while(bac[sg[x]]==clo) ++sg[x];return sg[x];}void work(){memset(sg,-1,sizeof(sg));//for(int i=1;i<=1000;i++) printf("%d\n",find(i));//exit(0);int now=1,ans(0);for(int i=1;i<=n;i++){if(a[i]){ans^=find(now);now=0;}else ++now;}++now;ans^=find(now);if(ans) printf("YES\n");else printf("NO\n");}
}A;struct BB{int sg[N][3][3];int bac[N],clo;int find(int x,int l,int r){if(!l&&!r) return x&1;else if(!l||!r) return x;else return l==r;if(x==0) return 0;if(sg[x][l][r]!=-1) return sg[x][l][r];for(int i=1;i<=x;i++){for(int j=1;j<=2;j++){if(i==1&&j==l) continue;if(i==x&&j==r) continue;find(i-1,l,j);find(x-i,j,r);}}++clo;for(int i=1;i<=x;i++){for(int j=1;j<=2;j++){if(i==1&&j==l) continue;if(i==x&&j==r) continue;bac[find(i-1,l,j)^find(x-i,j,r)]=clo;}}sg[x][l][r]=0;while(bac[sg[x][l][r]]==clo) ++sg[x][l][r];//printf("x=%d (%d %d) sg=%d\n",x,l,r,sg[x][l][r]);return sg[x][l][r];}void work(){memset(sg,-1,sizeof(sg));int now=0,lst=0,ans=0;for(int i=1;i<=n+1;i++){if(a[i]||i>n){ans^=find(now,lst,a[i]);now=0;lst=a[i];}else ++now;//printf("i=%d now=%d lst=%d ans=%d\n",i,now,lst,ans);}ans^=find(now,lst,0);if(ans) puts("YES");else puts("NO");}
}B;struct CC{void work(){int num(0);for(int i=1;i<=n;i++) num+=(a[i]==0);if(num&1) puts("YES");else puts("NO");}
}C;signed main(){freopen("color.in","r",stdin);freopen("color.out","w",stdout);n=read();m=read();for(int i=1;i<=n;i++) a[i]=read();if(m==1) A.work();else if(m==2) B.work();else C.work();return 0;
}
/*
*/
T3
调不出来了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=1e5+100;
const int mod=998244353;int n,m;
ll f[350][150],mi[8],b;
int a[8],vis[8],pl[8],id[8];
double ans;
void calc(){for(int i=1;i<=n;i++) id[pl[i]]=i;memset(f,0,sizeof(f));f[a[1]*n+1][1]=1;for(int i=1;i<=n*m;i++){int k=(i-1)%n+1;for(int s=0;s<mi[n];s++){if(s&mi[k-1]) continue;for(int p=i;p<=n*m;p++){f[min(n*m+1,max(p,i+a[k]*n))][s|mi[k-1]]+=f[p][s];}}}ans+=1.0*f[n*m+1][mi[n]-1];
}
int clo;
void dfs(int k){if(k>n){calc();++clo;return;}for(int i=2;i<=n;i++){if(vis[i]) continue;pl[k]=i;vis[i]=1;dfs(k+1);vis[i]=0;}return;
}signed main(){freopen("circle.in","r",stdin);freopen("circle.out","w",stdout);n=read();m=read();b=1;for(int i=1;i<n;i++) b*=m*i;for(int i=1;i<=n;i++) a[i]=read();sort(a+1,a+1+n);swap(a[1],a[n]);mi[0]=1;for(int i=1;i<=n;i++) mi[i]=mi[i-1]<<1;vis[1]=1;pl[1]=1;dfs(2);//for(int i=1;i<n;i++) ans/=i;ans/=b;//ans*=2;printf("%.12lf\n",ans);//printf("b=%lld clo=%d\n",b,clo);return 0;
}
/*
4 6
1 2 3 4
*/
总结
今天整体还不错,没有挂分。
ybt机子的锅就不算了吧。