时间
8:30~8:50 看题,T1KMP?T2一眼看到了第一档分的暴力,然后看T3,脑海中只有一个思路,就是硬跑树,任意的两个点都求出lca,然后再 n 3 n^3 n3的枚举,当时就被这复杂度吓到了,但看完数据范围,应该是50分。
8:50~9:40 T1,写了自己创造的KMP,对于不是特殊构造的题来说,这样写会比普通的KMP快,中间含有剪枝。
9:40~11:00 T2,先写了 n 2 n^2 n2的暴力,然后就开始想正解,当画出菱形后,觉得,这可以用set来写,每次直接lower_bound,但是卡到了指针it没法和int类型进行加减操作,卡住,又换成数组,又发现set好像不能存负数,调来调去,自闭。
11:30~12:10 T3,写的非常顺利,直接安装最暴力的思路,原本想用trajan,但是并不容易,码的倍增。
12:10~13:00 又开始调T2,把数组换成map,把x,y统一加上一个数,转换成正数,又试了好久,自闭,一直不对,卡到了边界条件。
题目
T1
只有60分,竟然是捆绑测试,并且T1的数据并不是随机的,而是专门构造的。写的时候就应该想到,因为如果是随机的,答案不就是很小,所以这肯定是特殊构造。正解是hash,移动的时候是O(n),hash也是今天才会的,字符串hash的具体的代码:
typedef unsigned long long ull;
const int N=1e6+20,base=131;
ull f[N],h[N];
char a[N];
bool check(int l,int i,int j,int r)
{
if(h[i]-h[l-1]*f[i-l+1]==h[r]-h[j-1]*f[r-j+1]) return true;
return false;
}
int main()
{
f[0]=0;
for(int i=1;i<=1e6;i++)
f[i]=base*f[i-1];
cin>>a+1;
for(int i=1;i<=strlen(a);i++)
h[i]=h[i-1]*base+int(a[i]-'a');
if(check(l,i,j,r)==true) cout<<1;
return 0;
}
T2
正解是曼哈顿距离转成切比雪夫距离,然后用树状数组来维护,至于这个距离是怎么转化的,奉上一篇博客:曼哈顿距离和切比雪夫距离的相互转化。
T3
机房大佬bitset写的80分,然后就开始了学习bitset,没错,这已经不晓得是啥时候学的了,首先,bitset可以写成代替bool类型,并且内存的消耗是要小于bool类型的,是可以把数组开的更大,大约是3e9,所以,代替的bool类型的二维数组应该可以拿到1e4的这一档分了吧。不过超过的也可以尝试着去写hash,来存。
bitset<1e4>s[1e4];
反思
本次考试的暴力拿到,但是更高一档的分数,啥都没拿到,T1值得反思,一定要注意随机的数据和人造数据之间的差别,而自己的写法是要进行选择的。