NOIP 2023

· · 个人记录

Day 1

T1

喜提 $3s$。 简单修改 $1$ 小时后通过。/lh cpp 无法释放 fc,cmd 亦无法释放 fc。 炸裂。 只能大眼观察了。 ```cpp #include <iostream> #include <cstdio> #include <cctype> #include <algorithm> using namespace std; #define MAXN 3005 inline int read() { int f=1,x=0; char c=getchar(); while(!isdigit(c)) {if(c=='-') {f=-1;} c=getchar();} while(isdigit(c)) {x=x*10+c-'0';c=getchar();} return f*x; } int n,m; char c[MAXN][MAXN]; char c1[MAXN],c2[MAXN]; char now[MAXN],res[MAXN]; void srt(char s[MAXN]) { int i,j; int t[26]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; for(i=1;i<=m;i++) { t[s[i]-'a']++; } for(i=1,j=0;i<=m;i++) { while(t[j]==0)j++; t[j]--; s[i]=j+'a'; } } void rev(char s[MAXN]) { int i; for(i=1;i*2<=m;i++) { swap(s[i],s[m-i+1]); } } int cmp(char s1[MAXN],char s2[MAXN]) { int i; for(i=1;i<=m;i++) { if(s1[i]<s2[i]) { return 1; } if(s2[i]<s1[i]) { return 2; } } return 0; } void cpy(char s1[MAXN],char s2[MAXN]) { int i; for(i=1;i<=m;i++) { s1[i]=s2[i]; } } signed main() { freopen("dict.in","r",stdin); freopen("dict.out","w",stdout); int i; n=read(),m=read(); for(i=1;i<=m;i++) { c1[i]=c2[i]='z'+1; } for(i=1;i<=n;i++) { cin>>(c[i]+1); cpy(now,c[i]); srt(now); rev(now); if(cmp(now,c1)==1) { cpy(c2,c1); cpy(c1,now); } else if(cmp(now,c2)==1) { cpy(c2,now); } } for(i=1;i<=n;i++) { if(cmp(c[i],c1)==0) { cpy(now,c2); } else { cpy(now,c1); } cpy(res,c[i]); srt(res); if(cmp(res,now)==1) { cout<<1; } else { cout<<0; } } return 0; } ``` ### T2 easy,忽略双向边,直接无脑释放 `2-sat`。 $1$ 小时后通过。 `dev` 栈空间扩大失败,炸裂。 启动 `NOI-linux` 直接运行,通过样例四。 忘记 `diff` 尝试使用 `fc` 失败。 ```cpp #include <iostream> #include <cstdio> #include <cctype> #include <algorithm> #include <cstring> using namespace std; #define MAXN 200005 inline int read() { int f=1,x=0; char c=getchar(); while(!isdigit(c)) {if(c=='-') {f=-1;} c=getchar();} while(isdigit(c)) {x=x*10+c-'0';c=getchar();} return f*x; } int C,T; int n,m; int a[MAXN];//我们认定 n+1,2,3 为 TUF int rev(int x) {if(x>n) {return n+4-(x-n);} return -x;}///我有特殊取反技巧 struct edge {int to,next,dis;} e[MAXN*10];///我们认为 T 是 x F 是 x+n int cnt,head[MAXN*2]; void add(int x,int y,int z) {cnt++;e[cnt].to=y;e[cnt].dis=z;e[cnt].next=head[x];head[x]=cnt;}/// 1 + 0 - void add(int x,int y) {cnt++;e[cnt].to=y;e[cnt].next=head[x];head[x]=cnt;} int vis[MAXN]; int ans[MAXN]; void dfs(int x) { vis[x]=1; for(int i=head[x];i;i=e[i].next) { int v=e[i].to; if(!ans[v]&&!vis[v]) { ans[v]=e[i].dis?ans[x]:rev(ans[x]); dfs(v); } } } int dfx,dfn[MAXN*2],low[MAXN*2],book[MAXN*2]; int st[MAXN*2],tot; int col,scc[MAXN*2]; void tarjan(int x) { dfn[x]=low[x]=++dfx; st[++tot]=x; vis[x]=1; for(int i=head[x];i;i=e[i].next) { int v=e[i].to; if(!dfn[v]) { tarjan(v); low[x]=min(low[x],low[v]); } else if(vis[v])///不记得力 { low[x]=min(low[x],dfn[v]); } } if(dfn[x]==low[x]) { col++; while(st[tot]!=x) {scc[st[tot]]=col;vis[st[tot]]=0;tot--;} scc[st[tot]]=col;vis[st[tot]]=0;tot--; } } void clear() { memset(ans,0,sizeof(ans)); memset(vis,0,sizeof(vis)); memset(head,0,sizeof(head)); memset(dfn,0,sizeof(head)); memset(low,0,sizeof(head)); memset(scc,0,sizeof(scc)); memset(book,0,sizeof(book)); cnt=0; dfx=0; tot=0; col=0; } signed main() { freopen("tribool.in","r",stdin); freopen("tribool.out","w",stdout); int i; C=read(),T=read(); while(T--) { n=read(),m=read(); for(i=1;i<=n;i++) {a[i]=i;} for(i=1;i<=m;i++) { char op; cin>>op; if(op=='+') {int x=read(),y=read();a[x]=a[y];} if(op=='-') {int x=read(),y=read();a[x]=rev(a[y]);} if(op=='T') {int x=read();a[x]=n+1;} if(op=='U') {int x=read();a[x]=n+2;} if(op=='F') {int x=read();a[x]=n+3;} } for(i=1;i<=n;i++) { if(a[i]<=n) { if(a[i]>0) {add(i,a[i],1);add(a[i],i,1);} else {add(i,-a[i],0);add(-a[i],i,0);} } else {ans[i]=a[i];} } for(i=1;i<=n;i++) {if(ans[i]&&vis[i]==0) {dfs(i);}} memset(head,0,sizeof(head)); cnt=0; for(i=1;i<=n;i++) { if(a[i]<=n) { if(a[i]>0) {add(i,a[i]);add(a[i],i);add(i+n,a[i]+n);add(a[i]+n,i+n);} else {add(i+n,-a[i]);add(-a[i],i+n);add(i,-a[i]+n);add(-a[i]+n,i);} } } for(i=1;i<=2*n;i++) {if(!dfn[i]) {tarjan(i);}} for(i=1;i<=n;i++) {if(scc[i]==scc[i+n]) {ans[i]=n+2;}} int res=0; for(i=1;i<=n;i++) {if(ans[i]==n+2) {res++;}} cout<<res<<endl; clear(); } return 0; } ``` ### T3 简单写个 $35$ 卡在 $1.2s$ 卡常半小时,`dev` 出现编译运行 `exe` 不匹配症状,可怕,启动 `NOI-linux` 直接运行,卡进 $1.1s$ ,去做 T4。 T4 做完想起来没开 O2,启动 O2,不用卡了。 八连通,有点不多的想法,但是再见。 ```cpp #include <iostream> #include <cstdio> #include <cctype> #include <algorithm> using namespace std; #define MAXN 2005 #define MAXC 2005 inline void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) {c=getchar();} while(isdigit(c)) {x=x*10+c-'0';c=getchar();} } int C,n,m,q; int X[MAXN],Y[MAXN]; int a[MAXN],b[MAXN]; bool f[MAXC][MAXC],g[MAXC][MAXC];///X>Y X<Y bool solvef() { f[0][1]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { f[i][j]=(a[i]>b[j])&(f[i-1][j]|f[i][j-1]|f[i-1][j-1]); } } return f[n][m]; } bool solveg() { g[0][1]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { g[i][j]=(a[i]<b[j])&(g[i-1][j]|g[i][j-1]|g[i-1][j-1]); } } return g[n][m]; } inline bool solve() { return (a[1]>b[1]?solvef():(a[1]<b[1]?solveg():0)); } signed main() { freopen("expand.in","r",stdin); freopen("expand.out","w",stdout); int i; read(C),read(n),read(m),read(q); for(i=1;i<=n;i++) {read(X[i]);a[i]=X[i];} for(i=1;i<=m;i++) {read(Y[i]);b[i]=Y[i];} putchar((char)(solve()+'0')); int kx,ky; while(q--) { read(kx),read(ky); for(i=1;i<=n;i++) {a[i]=X[i];} for(i=1;i<=m;i++) {b[i]=Y[i];} int p; while(kx--) {read(p);read(a[p]);} while(ky--) {read(p);read(b[p]);} putchar((char)(solve()+'0')); } return 0; } ``` ### T4 T2 写完后看了一眼,感觉 easy 线段树 DP。 T3 写完没卡常还剩一个小时。 先写个 $36$ 分 DP。 小孩子不懂事, T3 卡着玩,卡了半小时启动 O2。 然后就再见。 ```cpp #include <iostream> #include <cstdio> #include <cctype> #include <algorithm> #include <cstring> using namespace std; #define MAXN 3005 #define ll long long inline int read() { int f=1,x=0; char c=getchar(); while(!isdigit(c)) {if(c=='-') {f=-1;} c=getchar();} while(isdigit(c)) {x=x*10+c-'0';c=getchar();} return f*x; } int C,T; int n,m,k,d; ll sum[MAXN][MAXN]; ll f[MAXN][MAXN]; signed main() { freopen("run.in","r",stdin); freopen("run.out","w",stdout); int i,j; C=read(),T=read(); while(T--) { memset(sum,0,sizeof(sum)); memset(f,0,sizeof(f)); n=read(),m=read(),k=read(),d=read(); while(m--) {int x=read(),y=read(),v=read();sum[x][y]+=v;} for(i=1;i<=n;i++) {for(j=1;j<=k;j++) {sum[i][j]+=sum[i][j-1];}} for(i=1;i<=n;i++) { for(j=0;j<=k;j++) { f[i][0]=max(f[i][0],f[i-1][j]); } for(j=1;j<=k;j++) { f[i][j]=f[i-1][j-1]+sum[i][j]-d; } } ll ans=0; for(i=0;i<=k;i++) ans=max(ans,f[n][i]); cout<<ans<<endl; } return 0; } ``` ## 后记 现役选手湖北只有外校会 T3。/cf