[2024.11.11]NOIP模拟赛T2
赛时
T1 提议看懂以后立马意识到就是让求最长Border。
对于 \(n\times m\le 10^6\) 可以暴力建串然后直接 KMP。
容易发现如果 \(s\) 循环元为 \(n\),那么答案就是 \(n\times (m-1)\)。
否则加上最长循环元长度即可。
循环元还是用 KMP 求。
T2 让我想起了之前一道硬控我 3h 的题目。
先把 \(n\le 500\) 写了,然后开始推 \(k=1\),发现是一个二阶等差数列求和,答案是一个三次多项式。
于是我开始在纸上画,发现需要根据 \(n\) 的奇偶性分类讨论。
结合前天 ABC-E 的贡献求法,累加答案,然后根据 \(\sum_{i=1}^{n}i^2=\frac{n(n-1)(2n-1)}{6}\) 这个式子硬推+化简可以发现这种情况下 \(n\) 为偶数时的答案是 \(\frac{2}{3}n^3-\frac{1}{2}n^2+\frac{1}{3}n\)。
其实一开始认为奇数的答案是一样的,但是样例过不去,然后发现此时贡献的分段界点会有变化,所以差别会很大。
然后我引入一个变量 \(x=\lfloor n/2\rfloor\) 代表分界点,按照刚才的方法继续推,加上分界点新产生的贡献,终于发现这个答案是 \(2nx^2-\frac{4}{3}x(x-1)(2x-1)+2x(2n-3x+1)+1\)。(想吐)
这个思路特别有前途,因为 \(k\neq1\) 时除了初始项的值中间的二次差值是不变的。
先想 \(op=1\) 的部分,结合差值的增量发现此时的分界点是 \(n-k+1\over 2\)。
有了这个,我再引入一个变量 \(x=\frac{n-k+1}{2}\),就可以按照刚才的思路继续推了。依然需要根据奇偶性分类考虑,然后我发现偶数的答案是 \(2nx(2x-1)-\frac{4}{3}x(x-1)(2x-1)-2x(x-1)\)。
本来想继续推奇数的,但是看着已经 11:00 了,就打算先把这些写了。
然后写着写着发现特别难调,然后我就调到了 11:50。
嗯,这下这个蛇型矩阵就一共硬控我 3+3=6h 了。
此时我 T2 的期望是 40pts。
赛后
发现 T2 我每次都输出了 \(ans\) 导致爆蛋,成功拿下机房倒数。
看见有人前三题都过了,瞬间意识到自己是个废物。
没办法,继续推 T2。
又推了 10min 得出 \(n\) 为奇数的答案是 \(2nx(2x+1)-\frac{4}{3}x(x-1)(2x-1)-6x^2+2x+k\)。
调了 20min 后成功获得 70pts。
开始讲题了,大概懂了 T3T4 的思路。
继续写 T2。
现在剩下 \(op=2\),发现分界点 \(x\) 依然是 \(n-k+1\over 2\)。
因为彼此之间是旋转 180° 的关系,我觉得两种情况是类似的。
然后推着推着我发现差别大的远超出预期。
但好在基本思路不变,然后我发现 \(n\) 为 偶数的答案是 \(2x(x-1)(2n-3)-\frac{4}{3}x(x-1)(2x-1)+6nx-4x\)。
最后一种情况了,冲!
好在不难,又推了一会发现答案是 \(2x(x-1)(2n-3)-\frac{4}{3}x(x-1)(2x-1)+6nx-4x-k-2+4n(x+1)-4x(x+2)\)。
虽然但是,用心的你能发现当这种东西出现 \(\%=998244353\) 时,想出来和码出来和过掉之间的距离就不是一般的大了。
然后我又被硬控了 1h。
终于过掉了。
发现自己用时最短。
我尝试删掉暴力那一档分段,然后发现自己用时是标程的 \(0.39\) 倍,空间是标程的 \(0.74\) 倍。
嗯……虽然但是 T3T4 连暴力都没写,大考中这样的话就真的废了。
但是好在我认为 NOIP 不会出这种题目。
T3 听懂以后发现并不难,关键是发现新图重构树的性质和转化题意。
T4 也是有分可拿。
这场 T2 和之前那场一样都是规律题,一旦开始写就感觉写不出来很亏,以至于浪费了全部时间。
但是同时我意识到自己赛时还是思维能力不足的表现。
彩蛋:我的 T2 代码:
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int w=1,s=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
return w*s;
}
const int maxn=2e6+10;
const int mod=998244353;
const int inf=1e9+7;
int n,op,k;
int ans=0;
int x,y;
int a[5010][5010];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
void Sub(int X,int Y)
{
int nd=0,nt=1;
int x=1,y=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=0;
while(nt<=n*n)
{
a[x][y]=nt;
int xx=x+dx[nd],yy=y+dy[nd];
if(xx<1||xx>n||yy<1||yy>n||a[xx][yy])
{
nd=(nd+1)%4;
xx=x+dx[nd],yy=y+dy[nd];
}
x=xx,y=yy;nt++;
}
x=X,y=Y;
int res=0;
while(x<=n&&y<=n)
{
(res+=a[x][y])%=mod;
x++;y++;
}
ans^=res;
return ;
}
int qw(int x,int y)
{
int res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
int inv3,inv2;
void Main()
{
n=read(),op=read(),k=read();
if(op==1)x=k,y=1;
else x=1,y=k;
int res=0;
if(k==1)
{
if(n%2==0)
{
res = res + n * n % mod * n % mod * 2 % mod * inv3 % mod;
res%=mod;
res=res + n * inv3 % mod;
res%=mod;
res=res - n * n % mod * inv2 % mod;
res=(res%mod+mod)%mod;
ans^=res;
return ;
}
int x=n/2;
res=res + 4 * n % mod * x % mod * (x-1) % mod;
res%=mod;
res=res + n * 2 % mod * x % mod;
res%=mod;
res=res - 4 * x % mod * (x-1) % mod * (2*x-1) % mod * inv3 % mod;
res=(res%mod+mod)%mod;
res=res - 2 * x % mod * (x-1) % mod;
res=(res%mod+mod)%mod;
res=res + 1 + 4 * x % mod * (n - x) % mod;
res%=mod;
ans^=res;
return ;
}
if(op==1)
{
if((n-k)&1)
{
int x=(n-k+1)/2;
res = res + 4 * x % mod * (x-1) % mod * n % mod;
res%=mod;
res = res - 4 * x % mod * (x-1) % mod * (2*x-1) % mod * inv3 % mod;
res=(res+mod)%mod;
res = res - 2 * x * (x-1) % mod;
res=(res+mod)%mod;
res = res + 2 * n % mod * x % mod;
res%=mod;
ans^=res;
return ;
}
int x=(n-k+1)/2;
res = res + 4 * x % mod * (x-1) % mod * n % mod;
res%=mod;
res = res - 4 * x % mod * (x-1) % mod * (2*x-1) % mod * inv3 % mod;
res=(res%mod+mod)%mod;
res = res - 2 * x % mod * (x-1) % mod % mod;
res=(res%mod+mod)%mod;
res = res + 2 * n % mod * x % mod;
res%=mod;
res = res + k + 4 * x % mod * (n-x) % mod;
res%=mod;
ans^=res;
return ;
}
if((n-k)&1)
{
int x=(n-k+1)/2;
res = res + 2 * (n-2) * x % mod * (x-1) % mod;
res%=mod;
res = res - 4 * x * (x-1) % mod * (2*x-1) % mod * inv3 % mod;
res=(res%mod+mod)%mod;
res = res + 2 * (n-1) % mod * x % mod * (x-1) % mod;
res%=mod;
res = res + 6 * n % mod * x % mod;
res%=mod;
res = res - 4 * x % mod;
res=(res%mod+mod)%mod;
ans^=res;
return ;
}
int x=(n-k+1)/2;
res = res + 2 * (n-2) * x % mod * (x-1) % mod;
res%=mod;
res = res - 4 * x * (x-1) % mod * (2*x-1) % mod * inv3 % mod;
res=(res%mod+mod)%mod;
res = res + 2 * (n-1) % mod * x % mod * (x-1) % mod;
res%=mod;
res = res + 6 * n % mod * x % mod;
res%=mod;
res = res - 4 * x % mod - k - 2;
res=(res%mod+mod)%mod;
res = res + 4 * n % mod * (x+1) % mod;
res%=mod;
res = res - 4 * x % mod * (x+2) % mod;
res=(res%mod+mod)%mod;
ans^=res;
return ;
}
signed main()
{
#ifdef Lydic
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#else
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
#endif
inv3=qw(3,mod-2);
inv2=qw(2,mod-2);
int T=read();
while(T--)Main();
cout<<ans<<endl;
return 0;
}