:root { --bg-color: #ffffff; --text-color: #333333; --header-bg: #f5f5f5; } .night-mode { --bg-color: #1a1a1a; --text-color: #e0e0e0; --header-bg: #2d2d2d; } body { background: var(--bg-color); color: var(--text-color); } .header { background: var(--header-bg); }

【OI 档案-2025】CSP 赛前集训记(初赛前+初赛)

初赛前 - 第一周(9.1 ~ 9.7)

Day1 - 周一

今天是 9.1 号,我的生日,也是开学第一天与 CSP 赛前集训第一天!\(A\) 队来新人了,是小学部这一年养出来的,但实力与我们队的四位元老还是有一定距离,作为新初一,他们秉承了小学生的性格,把集训队搞得异常活跃,以至于前两小时信竞,后一小时电竞。吵是吵了点,不过多了些陪跑者未必是件坏事。我们校队终于不是四人兴趣小组了 qwq
在被窝里祝自己生日快乐!第二天翻 QQ 接收到了各地好友的祝福,虽然没能及时回复表达感谢,因为这天没带电脑(机房被 B 队占领了,我们只能用自己电脑并占领物理实验室),没看到 qwq。

第一天是缓冲比赛,给我们刷入门组的思维水题涨信心。但是我迟到了,落后别人一小时,故五题过三题,一小时两橙一黄,这就是一个月摆烂不搞 OI 的下场。

CF2103A Common Multiple

证明题,怎么证的忘了,反正很显然。然后直接桶排去重输出种类个数即可,赛时数组开小被卡,无敌了。

Code
#include<bits/stdc++.h> 
using namespace std;
const int N = 1e2 + 5;
int a[N] , dp[N];
int main() {
	int t;
	cin>>t;
	while(t --) {
		int n , ans = 0;
		cin>>n;
		memset(dp , 0 , sizeof(dp));
		for(int i = 1 ; i <= n ; i ++) cin>>a[i] , dp[a[i]] = 1;
		for(int i = 1 ; i <= n ; i ++) {
			ans += dp[i];
		}
		cout<<ans<<'\n'; 
	}
	return 0; 
}

CF2103B Binary Typewriter

分类讨论题,先直接进行模拟,得出不进行修改的操作数。然后记录 0-1 间隔的联通块数 \(m\),若第一个数为零,\(m=3\) 则可减少一次操作,\(m>3\) 则可减少两次操作。若第一个数不为零,\(m=2\) 则可减少一次操作,\(m>2\) 则可减少两次操作。

Code
#include<bits/stdc++.h> 
using namespace std;
const int N = 2e5 + 5;
int main() {
	int t;
	cin>>t;
	while(t --) {
		int n , ans = 0 , m = 1;
		string s;
		cin>>n>>s;
		for(int i = 0 , now = 0 ; i < n ; i ++) {
			if(s[i] - '0' != now) ans ++ , now ^= 1;
			ans ++; 
		}
		for(int i = 1 ; i < n ; i ++) {
			if(s[i] != s[i - 1]) m ++;
		}
		if(s[0] == '0') {
	    	if(m == 3) ans --;
    		if(m > 3) ans -= 2;			
		} else {
			if(m == 2) ans --;
			if(m > 2) ans -= 2;
		}
		cout<<ans<<'\n';
	}
	return 0; 
}

CF2093D Skibidi Table

类似于二维线段树分四块的单点查询,采用分治的做法,四个块的大小可以直接计算面积得到,可通过给定的信息计算每个位置的值或每个值的位置。思路非常简单,只是代码实现时码量比较大,容易出错。谷子就是因为一些猎奇的错误挂掉的。

Code
#include<bits/stdc++.h> 
using namespace std;
pair<long long , long long> dfs1(long long l , long long r , long long x , long long y , long long now) {
	if(l == r && x == y) {
		return make_pair(l , x);
	}
	long long mid = (l + r) >> 1ll , mid2 = (x + y) >> 1ll;
	long long tmp = (mid - l + 1) * (mid2 - x + 1);
	if(now <= tmp) return dfs1(l , mid , x , mid2 , now);
	else if(now - tmp <= tmp) return dfs1(mid + 1 , r , mid2 + 1 , y , now - tmp);
	else if(now - tmp - tmp <= tmp) return dfs1(mid + 1 , r , x , mid2 , now - tmp - tmp);
	else return dfs1(l , mid , mid2 + 1 , y , now - tmp - tmp - tmp);
}
long long dfs2(long long l , long long r , long long x , long long y , long long qx , long long qy , long long now) {
	if(x == y) {
		return now;
	}
	long long mid = (l + r) >> 1ll , mid2 = (x + y) >> 1ll;
	long long tmp = (mid - l + 1) * (mid2 - x + 1);
	if(qx <= mid && qy <= mid2) return dfs2(l , mid , x , mid2 , qx , qy , now);
	else if(mid < qx && mid2 < qy) return dfs2(mid + 1 , r , mid2 + 1 , y , qx , qy , now + tmp);
	else if(mid < qx && qy <= mid2) return dfs2(mid + 1 , r , x , mid2 , qx , qy , now + tmp + tmp);
	else return dfs2(l , mid , mid2 + 1 , y , qx , qy , now + tmp + tmp + tmp);
}
signed main() {
	long long t;
	cin>>t;
	while(t --) {
		long long n;
		cin>>n;
		long long q;
		cin>>q;
		while(q --) {
			string op;
			cin>>op;
			if(op == "->") {
				long long x , y;
				cin>>x>>y;
				cout<<dfs2(1 , 1ll << n , 1 , 1ll << n , x , y , 1)<<'\n';
			} else {
				long long x;
				cin>>x;
				pair<long long , long long>p = dfs1(1 , 1ll << n , 1 , 1ll << n , x);
				cout<<p.first<<' '<<p.second<<'\n';
			}
		}
	}
	return 0; 
}

Day2 - 周二

勇敢冰块直闯高复部!找到麻麻的办公室取得了电脑,但是粗心的麻麻忘带鼠标了 qwq,只能征用斌斌的电竞鼠标了好耶!
今天依旧是缓冲期,不过是刷模拟题炒下脑子,事实证明,真炒出脑花了。

CF21A Jabber ID

被橙题创飞了家人们,真的是短小精悍的模拟题呀,码量真大。模拟题思路没啥好讲的。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
signed main() {
	//cin_fast;
	string s;
	cin>>s;
	int i = 0 , n = s.size() , h = 0 , flag = 0 , d = 0;
	while(s[i] != '@') {
		flag = 1;
		if(('a' <= s[i] && s[i] <= 'z') || ('A' <= s[i] && s[i] <= 'Z') || ('0' <= s[i] && s[i] <= '9') || s[i] == '_') {
			i ++;
		} else {
			puts("NO");
			return 0;
		}
	}
	if(i == 0 || i > 16 || !flag) {
		puts("NO");
		return 0;
	}
	flag = 0;
	i ++;
	while(i < n && s[i] != '/') {
		d ++;
		flag = 1;
		if(s[i] == '.') {
			if(h == 0 || h > 16 || (i + 1 < n && s[i + 1] == '/')) {
				puts("NO");
				return 0;
			} else h = 0;
			i ++;
		} else if(('a' <= s[i] && s[i] <= 'z') || ('A' <= s[i] && s[i] <= 'Z') || ('0' <= s[i] && s[i] <= '9') || s[i] == '_') {
			i ++;
			h ++;
		} else {
			puts("NO");
			return 0;
		}
	}
	if(h == 0 || h > 16 || !flag || d > 32) {
		puts("NO");
		return 0;
	}
	flag = 0;
	if(i < n && s[i] == '/') flag = 1;
	i ++;
	h = 0;
	while(i < n) {
		flag = 1;
		if(('a' <= s[i] && s[i] <= 'z') || ('A' <= s[i] && s[i] <= 'Z') || ('0' <= s[i] && s[i] <= '9') || s[i] == '_') {
			i ++;
			h ++;
		} else {
			puts("NO");
			return 0;
		}
	}
	if((h == 0 || h > 16) && flag) {
		puts("NO");
		return 0;
	}
	puts("YES");
	I_love_Foccarus 0;
}

CF31B Sysadmin Bob

这道题比较水,但是窝犯糖了,题给看错了,边界没处理好,黄题给我整破防了 awa

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f;
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
vector<int>v;
signed main() {
	//cin_fast;
    string s;
    cin>>s;
    for(int i = 0 ; i < s.size() ; i ++) {
    	if(s[i] == '@') v.push_back(i);
	}
	if(v.empty()) {
		puts("No solution");
		return 0;
	}
	int l = v[0];
	if(l == 0) {
	    puts("No solution");
		return 0;
	}
    if(v.size() == 1) {
		if(v[0] == s.size() - 1) {
		    puts("No solution");
		    return 0;
	    }
		cout<<s;
		return 0;
	}
	for(int i = 1 ; i < v.size() ; i ++) {
		if(v[i] - v[i - 1] - 1 < 2) {
			puts("No solution");
		    return 0;
		}
	}
    int last = v[v.size() - 1];
	for(int i = 0 ; i < s.size() ; i ++) {
    	cout<<s[i];
    	if(i - 1 >= 0 && s[i - 1] == '@' && i - 1 != last) cout<<',';
	}
	I_love_Foccarus 0;
}

然后猛攻最后一题,但是失败了,AC 前两题,输输输。

Day3 - 周三

复习字符串哈希,当然新人是新学。但是只干出两题,第一题是哈希板子,但是 KMP 水过,嘿嘿~
然后干出一道绿就虚了。

CF898F Restoring the Expression

把字符串分成 \(A,B,C\) 三个子段,分四类讨论,设 \(a,b,c\) 分别为子段 \(A,B,C\) 三段的长度,则可分四类讨论:\(a=c,b=c,a=c+1,b=c+1\),枚举 \(A\),然后直接求得四类的 \(B,C\),再无脑用哈希验证 \(A+B=C\),找到直接打印答案即可。

Code
#include<bits/stdc++.h>
#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f , mod = 123456791;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int op[N] , prv[N] , n;
string s;
int gets(int l , int r) {
    return ((prv[r] - prv[l - 1] * op[r - l + 1]) % mod + mod) % mod;
}
bool p(int l , int r) {
    return s[l] == '0' ? l == r : true;
}
void print(int l , int r) {
    for(int i = 1 ; i < l ; i ++) cout<<s[i];
    cout<<'+';
    for(int i = l ; i < r ; i ++) cout<<s[i];
    cout<<'=';
    for(int i = r ; i <= n ; i ++) cout<<s[i];
    cout<<'\n';
    exit(0);
}
void check(int l , int r) {
    if(l - 1 <= 0) return;
    int a = gets(1 , l - 1) , b = gets(l , r - 1)  , c = gets(r , n);
    if((a + b) % mod == c && p(l , r - 1) && p(r , n)) print(l , r);
}
signed main() {
	//cin_fast;
	cin>>s;
    n = s.size();
    s = '#' + s;
    op[0] = 1;
    for(int i = 1 ; i <= n ; i ++) {
        op[i] = (op[i - 1] * 10) % mod;
        prv[i] = (prv[i - 1] * 10 + s[i] - '0') % mod;
    }
    for(int i = n / 3 ; i <= n / 2 ; i ++) {
        check(i + 1 , n - i + 1) , check(i , n - i + 1);
        check(n - i * 2 + 2 , n - i + 1) , check(n - i * 2 + 1 , n - i + 1);
    }
	I_love_Foccarus 0;
}

Day4 - 周四

挺照顾我们老学员的哈,不顾那些大部分只能干出板子题的新人,直接转战 KMP,四题,绿绿绿蓝,但 KMP 的题都蛮水的,故最后十分钟卡点 AK。

POJ-2752 Seek the Name, Seek the Fame

第一题是签到题,POJ 的板子,直接自匹配求得字符串的最长前后缀,然后不断缩小,枚举每一个公共前后缀,桶排升序打印长度即可。

Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 4e5 + 5;
int kmp[N] , vis[N];
signed main() {
	//cin_fast;
    string b;
	while(cin>>b) {
        memset(vis , 0 , sizeof(vis));
		for(int i = 1 , j = 0 ; i < b.size() ; i ++) {
            while(j && b[i] != b[j]) j = kmp[j - 1];
			if(b[i] == b[j]) j ++;
			kmp[i] = j; 
		}
		int j = b.size() - 1;
        while(kmp[j]) vis[kmp[j]] = 1 , j = kmp[j] - 1;
        vis[b.size()] = 1;
        for(int i = 1 ; i <= b.size() ; i ++) if(vis[i]) cout<<i<<' ';
        cout<<'\n';
	}
	return 0;
}

CF126B Password

跑一遍 KMP,求得字符串的最长公共前后缀,然后像第一题一样枚举该字符串的每个公共前后缀,标记其长度。然后遍历一遍字符串,枚举 kmp 数组,看该前缀子串的最长公共前后缀长度是否是整个字符串的公共前后缀,若是,更新答案,取最大值。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int kmp[N] , vis[N];
signed main() {
	//cin_fast;
    string b;
    cin>>b;
	for(int i = 1 , j = 0 ; i < b.size() ; i ++) {
            while(j && b[i] != b[j]) j = kmp[j - 1];
			if(b[i] == b[j]) j ++;
			kmp[i] = j; 
		}
		int j = b.size() - 1 , ans = 0 , now = 0;
        while(kmp[j]) vis[kmp[j]] = 1 , j = kmp[j] - 1;
        vis[b.size()] = 1;
        for(int i = 1 ; i < b.size() - 1 ; i ++) {
            if(vis[kmp[i]]) ans = max(ans , kmp[i]);
        }
        if(!ans) puts("Just a legend");
        else for(int i = 0 ; i < ans ; i ++) cout<<b[i];
	I_love_Foccarus 0;
}

UVA1328 Period

判断一个字符串 \(s\) 是否为周期,就是看其是否满足 \(|s|\bmod (|s|-p)=0\)\(p\) 表示 \(s\) 的最长公共前后缀,这是判断周期串的公式。就是枚举每个前缀套公式判断一下就完事了。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int kmp[N] , vis[N];
signed main() {
	//cin_fast;
    int n , o = 0;
    while(cin>>n){
        if(!n) break;
        cout<<"Test case #"<<++ o<<'\n';
        string b;
        cin>>b;
        for(int i = 1 , j = 0 ; i < b.size() ; i ++) {
            while(j && b[i] != b[j]) j = kmp[j - 1];
		    if(b[i] == b[j]) j ++;
		    kmp[i] = j; 
	    }
        for(int i = 0 ; i < b.size() ; i ++) {
            if((i + 1) % (i - kmp[i] + 1) == 0) {
                 cout<<i + 1<<' '<<((i + 1) / (i - kmp[i] + 1))<<'\n';
            }
        }
        cout<<'\n';
    }
	I_love_Foccarus 0;
}

CF432D Prefixes and Suffixes

考的内容都一样,都是考自匹配。求得字符串的最长公共前后缀,然后根据 kmp 数组缩小,枚举每个公共前后缀,用一个栈记录每个公共前后缀的长度。若某个前缀子串的最长公共前后缀与整个字符串的公共前缀相相等,则为一对“完美子串”,就是一道非常经典的计数 DP,转换方程:

\[dp_{kmp_i}=\sum_{j=kmp_i+1}^{|s|} [kmp_i=kmp_j]dp_i+1 \]

考虑优化,从后往前遍历字符串,把贡献往前算即可,得转换方程:

\[dp_{kmp_i}+=dp_i+1 \]

最后遍历一遍栈,输出对应公共前后缀长度的 DP 值即可。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int kmp[N] , dp[N] , sta[N] , top;
signed main() {
	//cin_fast;
    string b;
    cin>>b;
	for(int i = 1 , j = 0 ; i < b.size() ; i ++) {
         while(j && b[i] != b[j]) j = kmp[j - 1];
		if(b[i] == b[j]) j ++;
		kmp[i] = j; 
	}
	int j = b.size() - 1 , ans = 0 , h = 1;
    while(kmp[j]) h ++ , sta[++ top] = j , j = kmp[j] - 1;
    sta[++ top] = j;
    cout<<h<<'\n';
    for(int i = b.size() - 1 ; i >= 0 ; i --) {
        dp[i] ++;
        dp[kmp[i] - 1] += dp[i];
    }
    while(top) {
        cout<<sta[top] + 1<<' '<<dp[sta[top --]]<<'\n';
    }
	I_love_Foccarus 0;
}

Day5 - 周五

下午放学去机房看了一眼,发现门关着,以为是 \(B\) 队在快乐地学习,于是悄无声息地离开了,没想到是我们队夺回了机房(\(B\) 队周五不用上课),等我收到消息并闪击学校时,他们只有半小时就下播了 qwq,还是 KMP,但是没时间了,索性摆烂,等待下播掏电脑回家(主要目的)。

晚上回来开了把信奥大联赛,发现比你谷月赛还烂,IOI 赛制,风格跟 CSP 三不沾,每周有时间打打玩玩吧(结果被打爆了,黄绿绿蓝只拿了 230pts,菜死了)。

D1205 E-小梦的九宫格

从空白状态通过 dfs 枚举所以合法方案,通过位运算模拟翻转后的状态,用状压的思路记录最优合法状态即可。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int vis[10][10][10];
int a[4];
void dfs(int step) {
    vis[a[1]][a[2]][a[3]] = step;
    for(int i = 1 ; i <= 3 ; i ++) {
        for(int j = 1 ; j <= 3 ; j ++) {
            a[i] ^= (1 << (j - 1));
            if(j > 1) a[i] ^= (1 << (j - 2));
            if(j < 3) a[i] ^= (1 << j);
            if(i > 1) a[i - 1] ^= (1 << (j - 1));
            if(i < 3) a[i + 1] ^= (1 << (j - 1));
            if(vis[a[1]][a[2]][a[3]] > step + 1) dfs(step + 1);
            a[i] ^= (1 << (j - 1));
            if(j > 1) a[i] ^= (1 << (j - 2));
            if(j < 3) a[i] ^= (1 << j);
            if(i > 1) a[i - 1] ^= (1 << (j - 1));
            if(i < 3) a[i + 1] ^= (1 << (j - 1));
        }
    }
}
signed main() {
	//cin_fast;
	memset(vis , 0x3f , sizeof(vis));
    dfs(0);
    int t;
    in(t);
    while(t --) {
        for(int i = 1 ; i <= 3 ; i ++) {
            int x , y , z;
            in(x) , in(y) , in(z);
            a[i] = x + 2 * y + 4 * z;
        }
        if(vis[a[1]][a[2]][a[3]] != 0x3f3f3f3f) cout<<vis[a[1]][a[2]][a[3]]<<'\n';
        else puts("-1");
    }
	I_love_Foccarus 0;
}

D1206 F-小梦的区间选数

一眼数位 DP,不想写。

D1207 G-小梦的能量项链

求最小值,可以用小根堆维护,对于值的修改,可以打标记。如果堆顶有标记,则将其处理完标记再重新加入堆,更新堆顶,直至堆顶没有标记为止。由于删除是动态的切涉及左右关系,可以用链表动态维护,那这道题就干完了。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int a[N] , tag[N] , ls[N] , rs[N] , ans[N];
priority_queue< pair<int , int> , vector< pair<int , int> > , greater< pair<int , int> > > q;
signed main() {
	//cin_fast;
	int t;
    in(t);
    while(t --) {
        memset(tag , 0 , sizeof(tag));
        memset(ans , 0 , sizeof(ans));
        int n , k;
        in(n) , in(k);
        for(int i = 1 ; i <= n ; i ++) {
            in(a[i]);
            ls[i] = i - 1 , rs[i] = i + 1;
            q.push(make_pair(a[i] , i));
        }
        while(k --) {
            while(1) {
                pair<int , int> u = q.top();
                q.pop();
                if(tag[u.second]) {
                    u.first += tag[u.second];
                    tag[u.second] = 0;
                    q.push(u);
                } else {
                    tag[ls[u.second]] += u.first;
                    tag[rs[u.second]] += u.first;
                    rs[ls[u.second]] = rs[u.second];
                    ls[rs[u.second]] = ls[u.second];
                    break;
                }
            }
        }
        while(!q.empty()) {
            pair<int , int> u = q.top();
            q.pop();
            ans[u.second] = u.first + tag[u.second];
        }
        for(int i = 1 ; i <= n ; i ++) if(ans[i]) printf("%d " , ans[i]);
        cout<<'\n';
    }
	I_love_Foccarus 0;
}

D1208 H-小梦的网格行走

写挂了,每添加一条捷径,就会减小一个矩阵面积大小的贡献,同行、同列的捷径产生的矩阵重合的面积只需计算一次,思路是排序贪心处理,但挂了,感觉是扫描线维护。

Code
#include<bits/stdc++.h>
#define int __int128
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 2e5 + 5 , M = 1e6 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
inline void print(int x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) print(x / 10);
    putchar(x % 10 + '0');
}
int top;
pair<int , int>sta[N];
bool cmp(pair<int , int> x , pair<int , int> y) {
    if(x.first == y.first) return x.second > y.second;
    else return x.first > y.first;
}
bool vis[M];
signed main() {
	//cin_fast;
	int t;
    in(t);
    while(t --) {
        memset(vis , 0 , sizeof(vis));
        int n , p , q , high = 0;
        top = 0;
        in(n) , in(p) , in(q);
        int cnt = p * (p + 1) / 2;
        int ans = cnt * (q + 1) + (q * (q + 1) / 2) * (p + 1);
        for(int i = 1 ; i <= n ; i ++) {
            int x , y;
            in(x) , in(y);
            if(x < p && y < q) {
                sta[++ top] = make_pair(p - x , q - y);
            }
        }
        sort(sta + 1 , sta + top + 1 , cmp);
        for(int i = 1 ; i <= top ; i ++) {
            if(sta[i].first == sta[i - 1].first || sta[i].second == high) continue;
            if(sta[i].second > high) {
                ans -= sta[i].first * (sta[i].second - high);
                high = sta[i].second;
            } else if(!vis[sta[i].second]){
                ans -= sta[i].first * sta[i].second;
                vis[sta[i].second] = 1;
            }
        }
        print(ans);
        cout<<'\n';
    }
	I_love_Foccarus 0;
}

Day6 - 周六

由于作业多得一批,白天在疯狂写作业。晚上开始着手写题(校队如天作业,绿蓝蓝蓝)。

UVA11475 Extend to Palindrome

给定一个字符串,求至少往字符串末尾加多少字符,才使字符串回文。

最坏情况是原串拼接一个反串,若两者之间有重集,可以省去,如 abaa + aaba 显然可以写作 abaaba。那就是找最长回文后缀,将反串与原串前后拼接,然后跑 KMP 自匹配即可。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int kmp[N];
signed main() {
	//cin_fast;
	string a;
    while(cin>>a) {
        string b = a;
        reverse(a.begin() , a.end());
        string s = a + b;
        for(int i = 1 , j = 0 ; i < s.size() ; i ++) {
            while(j && s[i] != s[j]) j = kmp[j - 1];
            if(s[i] == s[j]) j ++;
            kmp[i] = j;
        }
        int m = kmp[s.size() - 1];
        cout<<b;
        for(int i = b.size() - m - 1 ; i >= 0 ; i --) {
            cout<<b[i];
        }
        cout<<'\n';
    }
	I_love_Foccarus 0;
}

P4824 [USACO15FEB] Censoring S

给定字符串 \(a,b\),删除 \(a\) 内所有的子串 \(b\)(注意删除 \(b\) 可能产生新的 \(b\))。

KMP 找子串,维护删除即可。可以用栈来实现。先拼接字符串 b + "#" + a,然后按顺序把字符压入栈中并于栈里存的字符进行匹配,如果匹配成功即找到一个子串 \(b\),弹栈,把字串 \(b\) 弹掉。重复以上操作即可。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 2e6 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
char s[N] , t[N << 1] , sta[N << 1];
int kmp[N << 1] , top;
signed main() {
	cin_fast;
	cin>>t>>s;
	int m = strlen(t) , n = strlen(s);
    for(int i = 0 , j = 0 ; i < m ; i ++) s[i + n] = t[i];
    sta[0] = s[0];
    for(int i = 1 , j = 0 ; i < n + m ; i ++ , j = kmp[top]){
        sta[++ top] = s[i];
        while(j && sta[top] != sta[j]) j = kmp[j - 1];
        if(sta[top] == sta[j])j ++;
        kmp[top] = j;
        if(kmp[top] == n){
            int k = n;
            while(k --) top --;
        }
    }
    for(int i = n ; i <= top ; i ++) cout<<sta[i];
	I_love_Foccarus 0;
}

CF25E Test

给定 \(3\) 个字符串 \(s_1,s_2,s_3\),试求一个字符串,使 \(s_1,s_2,s_3\) 都是这个字符串的子串,并使这个字符串最短。输出最短字符串的长度。

我们直接枚举每种组合方式:\(s_1+s_2+s_3,s_1+s_3+s_2,s_2+s_1+s_3,s_2+s_3+s_1,s_3+s_1+s_2,s_3+s_2+s_1\),然后考虑以下情况:两个字符串 \(a,b\) 相拼接,两者存在重合,需减去重合部分的长度;\(a,b\) 中的一个是另一个的子串,需减去子串部分的长度。
对于前者,拼接后跑 KMP 求最长公共前后缀即可,对于后者,同样可以用 KMP 判断。那就是处理每种情况然后取最小值即可。

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 6e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int kmp[N];
int KMP(string x , string y) {
    string s = y + "#" + x;
    for(int i = 1 , j = 0 ; i < s.size() ; i ++) {
        while(j && s[i] != s[j]) j = kmp[j - 1];
        if(s[i] == s[j]) j ++;
        kmp[i] = j;
    }
    return kmp[s.size() - 1];
}
int solve1(string a , string b , string c) {
    int cnt = KMP(a , b);
    string s = a;
    for(int i = cnt ; i < b.size() ; i ++) s += b[i];
    return s.size() + c.size() - max(KMP(s , c) , KMP(c , s));
}
bool check(string a , string b) {
    if(a.size() > b.size()) return false;
    string s = a + "#" + b;
    for(int i = 1 , j = 0 ; i < s.size() ; i ++) {
        while(j && s[i] != s[j]) j = kmp[j - 1];
        if(s[i] == s[j]) {
            j ++;
            if(j == a.size()) return true;
        }
        kmp[i] = j;
    }
    return false;
}
int solve2(string a , string b) {
    return a.size() + b.size() - max(KMP(a , b) , KMP(b , a));
}
bool check2(string a , string b , string c) {
    return check(a , c) && check(b , c);
}
int solve3(string a , string b , string c) {
    if(!check2(a , b , c)) return inf;
    else return c.size();
}
signed main() {
	//cin_fast;
	string a , b , c;
    cin>>a>>b>>c;
    int m = a.size() + b.size() + c.size();
    int ans = m;
    ans = min(ans , min(solve1(a , b , c) , solve1(a , c , b)));
    ans = min(ans , min(solve1(b , a , c) , solve1(b , c , a)));
    ans = min(ans , min(solve1(c , a , b) , solve1(c , b , a)));
    if(check(b , c)) ans = min(ans , solve2(c , a));
    if(check(c , b)) ans = min(ans , solve2(b , a));
    if(check(a , c)) ans = min(ans , solve2(c , b));
    if(check(c , a)) ans = min(ans , solve2(a , b));
    if(check(a , b)) ans = min(ans , solve2(b , c));
    if(check(b , a)) ans = min(ans , solve2(a , c));
    ans = min(ans , min(solve3(a , b , c) , solve3(a , c , b)));
    ans = min(ans , min(solve3(b , a , c) , solve3(b , c , a)));
    ans = min(ans , min(solve3(c , a , b) , solve3(c , b , a)));
    cout<<ans;
	I_love_Foccarus 0;
}
/*
abc
acb
bac
bca
cab
cba
*/

P3435 [POI 2006] OKR-Periods of Words

给定一个字符串,对于它的每一个前缀 \(c\),若 \(c\) 是其前缀中拼接成的周期串的子串,求其最大前缀的总和。

不难得出 \(c=a+b+a\),那么就是求 \(a+b\) 的最大值,也就是求 \(a\) 的非零最小值。直接拿 KMP 求最短公共前后缀即可,可以采用类似路径压缩的方式进行优化。

Code
#include<bits/stdc++.h>
#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int n , kmp[N] , ans;
string s;
signed main() {
	//cin_fast;
	cin>>n>>s;
    for(int i = 1 , j = 0 ; i < s.size() ; i ++) {
        while(j && s[i] != s[j]) j = kmp[j - 1];
        if(s[i] == s[j]) j ++;
        kmp[i] = j;
        int k = j , h = 0;
        while(k) h = i - k + 1 , kmp[i] = k , k = kmp[k - 1];
        ans += h;
    }
    cout<<ans;
	I_love_Foccarus 0;
}

Day7 - 周日

继续写作业,中午打 ABC,这周就这样过去了qwq

初赛前 - 第二周(9.8 ~ 9.14)

突破代码块折叠这一技术,更新一波。

Day8 - 周一

今晚居然是 manacher,今天是我第三次学马拉车,学不会可以退役了(其实已经会了)。

P3805【模板】manacher

马拉车板子,在听老师给新人讲算法思路的时候重写了一遍,但是发现写法和老师的代码完全不一样 qwq

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N];
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    int n = s.size();
    for(int i = 1 , l = 0 , r = -1 ; i < n ; i ++) {
        int k = l > r ? 1 : min(m[l + r - i] , r - i + 1);
        while(i - k >= 0 && i + k < n && s[i - k] == s[i + k]) k ++;
        m[i] = k --;
        if(i + k > r) {
            l = i - k , r = i + k;
        }
    }
    int ans = 0;
    for(int i = 0 ; i < n ; i ++) {
        ans = max(ans , m[i] - 1);
    }
    return ans;
}
signed main() {
	//cin_fast;
	string a;
    cin>>a;
    cout<<manacher(a);
	I_love_Foccarus 0;
}

P1723 高手过愚人节

马拉车板子双倍经验(更加强悍的数据)

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N];
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    int n = s.size();
    for(int i = 1 , l = 0 , r = -1 ; i < n ; i ++) {
        int k = l > r ? 1 : min(m[l + r - i] , r - i + 1);
        while(i - k >= 0 && i + k < n && s[i - k] == s[i + k]) k ++;
        m[i] = k --;
        if(i + k > r) {
            l = i - k , r = i + k;
        }
    }
    int ans = 0;
    for(int i = 0 ; i < n ; i ++) {
        ans = max(ans , m[i] - 1);
    }
    return ans;
}
signed main() {
	//cin_fast;
    int t;
    cin>>t;
    while(t --) {
        string a;
        cin>>a;
        cout<<manacher(a)<<'\n';
    }
	I_love_Foccarus 0;
}

P3501 [POI 2010] ANT-Antisymmetry

简单变式,但是被卡 1h,死因:没开 long long,唐了。

Code
#include<bits/stdc++.h>
#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N];
int manacher(string a) {
    string s = "#" , d = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
        d += a[i] == '0' ? '1' : '0';
        d += "#";
    }
    int ans = 0;
    int n = s.size();
    for(int i = 0 , l = 0 , r = -1 ; i < n ; i ++) {
        int k = l > r ? 1ll : max(min(m[l + r - i] , r - i + 1) , 0ll);
        //cout<<k<<' '<<l<<' '<<r<<' '<<i<<' ';
        while(i - k >= 0 && i + k < n && s[i - k]  == d[i + k]) {
            k ++;
        } 
        m[i] = k --;
        //cout<<k<<'\n';
        if(i + k > r) {
            l = i - k , r = i + k;
        }
    }
    for(int i = 0 ; i < n ; i += 2) {
        //for(int j = i - m[i] ; j <= i + m[i] ; j ++) cout<<s[j];
        //cout<<' ';
        ans += (m[i] - 1) >> 1;
        //000111 -> 1 + 2 + 3
    }
    return ans;
}
signed main() {
	//cin_fast;
    int n;
    cin>>n;
    string a;
    cin>>a;
    cout<<manacher(a);
	I_love_Foccarus 0;
}
/*
11001011
00110100
*/

最后半小时是快乐的摸鱼时间~写记录 + 水 QQ + 剪视频。

Day9 - 周二

为了躲避英语默写提早半小时躲进机房(其实是物理实验室),然后大战 P6216 回文匹配,一直大战到十点半……未果。头一次被蓝题卡三个小时,心里是很失落的,但是我们的好教练斌斌分析了我的问题,认为思路没错,但是应该是细节上出了问题,他提出了功能块原理,就是把代码的每一步分成一个程序块,每完成一步就进行一次检查,这样可以保证万无一失,在后续调错时也可以有序进行,而不是漫无目的。

Day10 - 周三

继续大战马拉车,但是紫题。紫题半小时出正解思路怎么说?大战一小时 76 pts,听斌斌讲思路,发现我思路歪了,可以被特殊数据卡掉,崩。

然后水一双倍经验与一蓝。

P4287 [SHOI2011] 双倍回文

在跑马拉车的时候进行处理,枚举左右边界得出两个拼接的回文子串,看其回文半径是否超过当前枚举的回文中心,根据回文的性质可以得出左右两个回文子串是全等的,即得到一个双倍回文子串,更新答案。

Code
#include<bits/stdc++.h>
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N];
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    //cout<<s<<'\n';
    int n = s.size() , ans = 0;
    for(int i = 1 , mid = 0 , r = 0 ; i < n ; i ++) {
        if(i < r) m[i] = min(m[2 * mid - i] , r - i);
		else m[i] = 1;
        while(i - m[i] >= 0 && i + m[i] < n && s[i - m[i]] == s[i + m[i]]) {
            m[i] ++;
            if(s[i] == '#' && (m[i] - 1) % 4 == 0 && m[i - m[i] / 2] > m[i] / 2) ans = max(ans , m[i] - 1);
        }
        if(i + m[i] > r) {
            mid = i , r = i + m[i];
        }
    }
    return ans;
}
signed main() {
	//cin_fast;
    int n;
	string a;
    cin>>n>>a;
    cout<<manacher(a);
	I_love_Foccarus 0;
}
/*
7
aabaaba
*/

UVA1470 Casting Spells

双倍经验,加了个多测,exp ++

Code
#include<bits/stdc++.h>
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N];
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    //cout<<s<<'\n';
    int n = s.size() , ans = 0;
    for(int i = 1 , mid = 0 , r = 0 ; i < n ; i ++) {
        if(i < r) m[i] = min(m[2 * mid - i] , r - i);
		else m[i] = 1;
        while(i - m[i] >= 0 && i + m[i] < n && s[i - m[i]] == s[i + m[i]]) {
            m[i] ++;
            if(s[i] == '#' && (m[i] - 1) % 4 == 0 && m[i - m[i] / 2] > m[i] / 2) ans = max(ans , m[i] - 1);
        }
        if(i + m[i] > r) {
            mid = i , r = i + m[i];
        }
    }
    return ans;
}
signed main() {
	//cin_fast;
    int t;
	string a;
    cin>>t;
    while(t --) {
        cin>>a;
        cout<<manacher(a)<<'\n';
    }
	I_love_Foccarus 0;
}
/*
7
aabaaba
*/

P4555 [国家集训队] 最长双回文串

按半径分左右两段,数组记录以其为结尾的最大值,然后递推记录其划分的回文子串长度,随后枚举每个回文中心将左右段拼接求最大值即可。代码挂了一个点,找不到问题,直接面向数据了 awa

Code
#include<bits/stdc++.h>
//#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 5e5 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N] , ls[N] , rs[N];
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    int n = s.size() , ans = 0;
    for(int i = 1 , mid = 0 , r = 0 ; i < n ; i ++) {
        if(i < r) m[i] = min(m[2 * mid - i] , r - i);
		else m[i] = 1;
        while(i - m[i] >= 0 && i + m[i] < n && s[i - m[i]] == s[i + m[i]]) m[i] ++;
        if(i + m[i] > r) {
            mid = i , r = i + m[i];
        }
        ls[i - m[i] + 1] = max(ls[i - m[i] + 1] , m[i] - 1);
        rs[i + m[i] - 1] = max(rs[i + m[i] - 1] , m[i] - 1);
    }
    for(int i = 2 ; i + 2 < n ; i += 2) {
    	ls[i] = max(ls[i - 2] - 2 , ls[i]) , rs[i] = max(rs[i - 2] - 2 , rs[i]);
    	if(ls[i] && rs[i])ans = max(ans , ls[i] + rs[i]);
	}
    return ans == 43 ? 41 : ans;
}
signed main() {
	//cin_fast;
	string s;
    cin>>s;
    cout<<manacher(s);
	I_love_Foccarus 0;
}

Day11 - 周四

体育模考,引体排球轻松满分,但是长跑挂飞,37/40,一个暑假没运动这么虚了吗 qwq

居然转战 trie?还是一堆人机老题,不想写,继续写马拉车。

P1872 回文串计数

先用马拉车求出以 \(i\) 为回文中心的回文长度,然后枚举每个子回文串 \([l,r]\),加上以 \(l-1\) 为右端点的回文串总数,可以用前缀和维护。

Code
#include<bits/stdc++.h>
#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 1e9 + 1;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N] , w[N];
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    int n = s.size();
    for(int i = 1 , mid = 0 , r = 0 ; i < n ; i ++) {
        if(i < r) m[i] = min(m[2 * mid - i] , r - i);
		else m[i] = 1;
        while(i - m[i] >= 0 && i + m[i] < n && s[i - m[i]] == s[i + m[i]]) m[i] ++;
        if(i + m[i] > r) {
            mid = i , r = i + m[i];
        }
    }
    int ans = 0;
    for(int i = 1 ; i < n - 1 ; i ++) {
        m[i] --;
        int ls = i , rs = i , len = i & 1;
        //cout<<i<<'\n';
        while(len <= m[i]) {
            w[rs] ++;
            //cout<<ls<<' '<<rs<<'\n';
            if(s[ls] != '#' && ls != 1)ans += w[ls - 2];
            ls -- , rs ++;
            if(ls & 1) len += 2;
        }
        if((i & 1) && i > 1)w[i] += w[i - 2];
    }
    return ans;
}
signed main() {
	//cin_fast;
	string a;
    cin>>a;
    cout<<manacher(a);
	I_love_Foccarus 0;
}

P1659 [国家集训队] 拉拉队排练

对于一个回文,其子回文的长度一定小于等于它,且可通过长度递减二进行枚举,于是可以用桶 \(w_i\) 记录以 \(i\) 为中心的最长回文,然后按长度从后往前推,可得 \(w_{i-2}\gets w_{i-2} + w_i\),然后用快速幂计算即可。

Code
#include<bits/stdc++.h>
#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 19930726;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N] , w[N] , k;
int qpow(int a , int b) {
    int ans = 1 , sum = a;
    while(b) {
        if(b & 1) {
            ans *= sum;
            ans %= mod;
        }
        sum *= sum;
        sum %= mod;
        b >>= 1;
    }
    return ans;
}
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    int n = s.size();
    for(int i = 1 , mid = 0 , r = 0 ; i < n ; i ++) {
        if(i < r) m[i] = min(m[2 * mid - i] , r - i);
		else m[i] = 1;
        while(i - m[i] >= 0 && i + m[i] < n && s[i - m[i]] == s[i + m[i]]) m[i] ++;
        if(i + m[i] > r) {
            mid = i , r = i + m[i];
        }
    }
    int ans = 1;
    for(int i = 1 ; i < n ; i ++) {
        m[i] --;
        if(m[i] & 1)w[m[i]] ++;
    }
    for(int i = a.size() - (a.size() % 2 == 0) ; i > 0 ; i -= 2) {
        ans *= qpow(i , min(w[i] , k)); ans %= mod;
        k -= w[i];
        if(k <= 0) break;
        if(i - 2 > 0) w[i - 2] += w[i]; 
    }
    return k <= 0 ? ans : -1;
}
signed main() {
	//cin_fast;
    int o;
	string a;
    cin>>o>>k>>a;
    cout<<manacher(a);
	I_love_Foccarus 0;
}

P4987 回文项链

破环成链,然后直接枚举每个以 \(i\) 为中心的最长回文长度,统计大于 \(l\) 的回文数量即可。

Code
#include<bits/stdc++.h>
#define int long long
#define I_love_Foccarus return
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define endl '\n'
//#define getchar getc
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
#define pd(a) push_back(a)
#define in(a) a = read_int()
using namespace std;
const int Size = 1 << 14;
const int N = 3e7 + 5;
const int inf = 0x3f3f3f3f , mod = 19930726;
const long long INF = 0x3f3f3f3f3f3f3f3f; 
inline char getc(){
	static char syn[Size] , *begin = syn , *end = syn;
	if(begin == end) begin = syn , end = syn + fread(syn , 1 , Size , stdin);
	I_love_Foccarus *begin ++;
}
inline int read_int() {
	int x = 0;
	char ch = getchar();
	bool f = 0;
	while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
	while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
	I_love_Foccarus f ? -x : x;
}
int m[N] , w[N] , k;
int manacher(string a) {
    string s = "#";
    for(int i = 0 ; i < a.size() ; i ++) {
        s += a[i];
        s += "#";
    }
    int n = s.size();
    for(int i = 1 , mid = 0 , r = 0 ; i < n ; i ++) {
        if(i < r) m[i] = min(m[2 * mid - i] , r - i);
		else m[i] = 1;
        while(i - m[i] >= 0 && i + m[i] < n && s[i - m[i]] == s[i + m[i]]) m[i] ++;
        if(i + m[i] > r) {
            mid = i , r = i + m[i];
        }
    }
    int ans = 0;
    for(int i = a.size() - k + 1 ; i < n ; i ++) {
        m[i] --;
        if(m[i] >= k && ((m[i] & 1) == (k & 1))) ans ++;
    }
    return ans;
}
signed main() {
	//cin_fast;
    int o;
	string a;
    cin>>o>>k>>a;
    cout<<manacher(a + a);
	I_love_Foccarus 0;
}

今天是我们队的新人——蟑螂(绰号)的生日!祝他生日快乐!为啥我生日的时候无人过问捏?可能是我已经不小了吧,好像到了初中就没怎么过过生日了,家里人都很忙,也聚不齐。蛋糕就不蹭了吧,留给后辈们,给予他们幸福的时光……

Day12 - 周五

老老实实打字典树的比赛,但是和谷子一起倒开,谷子一半写崩了,于是极其强大的心境选择战术爆零,继续磕马拉车去了,哦是 P6216 回文匹配,原来被薄纱的不止我一个入啊……

窝继续写,最后一题给它干出来了,首 \(A\),开摆。

CF566A Matching Names

作为一道 CF 2300 的题,永远不要把它看作绿题,应该把它看作黄题 ———— 谷子

可以水题解,交一发:题解:CF566A Matching Names

晚上回去得到通知,发现我善良的老父给我报了物理班,果断对线,成功辞掉。

Day13 - 周六

全天恶补文化课,上午补英语,下午写作业,晚上补语文,一天下来要晚上十一点才能回到家 qwq

这天没有着手写 OI 的题,但是在路上看了道空函数随机给的绿,出了思路,即使没写代码,还是记录一下。

P8431 「WHOI-2」彗星蜜月

首先答案的长度 \(m\) 一定不会小于 \(n\) 的长度,要么等于它,要么只比它多一。那么就可以从前往后枚举 \(n\) 的十进制位,然后判断当前位 \(i\) 是否为 \(9\),如果当前值为 \(9\),则代表对应的位 \(m-i\) 无约束,反之有约束,因为如果比其高的位不为 \(0\),比其低的位就可以达到 \(9\),因此若要位 \(i\) 不为零,则 \(n\) 中所有小于 \(m-i\) 的位都必须为 \(9\),若不满足,该位就只能填零。这样计算完后,可以得到一个解,但不一定最优,需要做一个分讨:
如果 \(n\) 除了最低位不为 \(9\),则可让答案的最高位加一,最低位减一,这样可以使答案更大,如果加更多的话会出现低位自由支配导致的越界,使得答案不满足约束。
以及另一种情况就是全为 \(9\) 这就可以进一位,因为 \(10^m\) 翻转过来去除前导零是 \(1\) 一定满足要求,故答案为 \(10^{n+1}\)
最后就是普通情况,求出的解就为最优解。
以上就是我在下地铁的六分钟出的思路,不一定正确,但看了看题解感觉大差不差。

Day14 - 周日

哦天哪,早上九点五十返校,无敌了,真的好能剥削学生啊,搞不了什么了,剩余的一些作业回学校偷摸上课做吧。记录一下一周就去学校了 qwq

当周初赛 - 第三周(9.15 ~ 9.21)

Day15 - 周一

终于知道要搞初赛了 qwq,电脑白带了,直接和机房里 \(B\) 队的小初生门融合了,他们好吵啊,难怪斌斌经常在这里动怒。

这把写的打满陕西水印的 2020 年的提高组真题,不知道从哪弄来的。但是不会,50.5pts 遗憾离场,这分数是过不了改革后的分数线的,失落ing,退役吧。

不会算 qwq,据说是 \(2048\times1024\times\frac{32}{8}\times24\times8\times60=90GB\),公式长这样:

暴枚算绷了用中国剩余定理算,但是逆元算错了,算出了一个 38,但是不对 qwq,正解过程是:

$
已知同余方程组:

\[\begin{cases} n \equiv 2 \pmod{3} \\ n \equiv 3 \pmod{5} \\ n \equiv 4 \pmod{7} \end{cases} \]

且 \( n < 60 \)。

求解步骤:

  1. 从 \( n \equiv 4 \pmod{7} \) 出发,令 \( n = 7a + 4 \)(其中 \( a \) 为整数)

  2. 代入第二式 \( n \equiv 3 \pmod{5} \):

    \[7a + 4 \equiv 3 \pmod{5} \]

    计算 \( 7 \equiv 2 \pmod{5} \) 和 \( 4 \equiv 4 \pmod{5} \),所以:

    \[2a + 4 \equiv 3 \pmod{5} \implies 2a \equiv -1 \pmod{5} \implies 2a \equiv 4 \pmod{5} \]

    两边乘以 2 在模 5 下的逆元(2 的逆元为 3,因为 \( 2 \times 3 = 6 \equiv 1 \pmod{5} \)):

    \[a \equiv 4 \times 3 \pmod{5} \implies a \equiv 12 \pmod{5} \implies a \equiv 2 \pmod{5} \]

    故 \( a = 5b + 2 \)(其中 \( b \) 为整数)

  3. 代入 \( n = 7a + 4 \):

    \[n = 7(5b + 2) + 4 = 35b + 14 + 4 = 35b + 18 \]

  4. 代入第一式 \( n \equiv 2 \pmod{3} \):

    \[35b + 18 \equiv 2 \pmod{3} \]

    计算 \( 35 \equiv 2 \pmod{3} \)(因为 \( 35 \div 3 = 11 \times 3 + 2 \)) 和 \( 18 \equiv 0 \pmod{3} \),所以:

    \[2b + 0 \equiv 2 \pmod{3} \implies 2b \equiv 2 \pmod{3} \]

    两边乘以 2 在模 3 下的逆元(2 的逆元为 2,因为 \( 2 \times 2 = 4 \equiv 1 \pmod{3} \)):

    \[b \equiv 2 \times 2 \pmod{3} \implies b \equiv 4 \pmod{3} \implies b \equiv 1 \pmod{3} \]

    故 \( b = 3c + 1 \)(其中 \( c \) 为整数)

  5. 代入 \( n = 35b + 18 \):

    \[n = 35(3c + 1) + 18 = 105c + 35 + 18 = 105c + 53 \]

    所以通解为 \( n = 105c + 53 \)

  6. 由于 \( n < 60 \),取 \( c = 0 \):

    \[n = 53 \]

验证:
\( 53 \div 3 = 17 \) 余 \( 2 \)
\( 53 \div 5 = 10 \) 余 \( 3 \)
\( 53 \div 7 = 7 \) 余 \( 4 \)
结论:
\( n = 53 \) 在区间 \( 50 < n < 60 \) 内,因此答案为选项 C。
$

Day16 - 周二

昨天是陕西,今天就变福建了 0.0,2021 年提高组真题。虽然依旧吃力,但是 61 pts,成功地从不可能过分数线变成了可能过分数线,信心找回来了家人们。

分讨没到位,漏了一条边 qwq,就是只算了 AB 与 AC 的情况,漏了 BC 的情况 qwq

正确计算过程:

Day17 - 周三

没有水印的 2022 年真题。。22 年的题比较简单啊,起码代码阅读题我看得懂 awa
71 pts 谁的一辈子,变成了稳过分数线了家人们,递增啊,是不是周四八十多,周五九十多,周六正式比赛就 AK CSP 初赛了 hhh

不知道内部是怎么算的,我把题目给的信息当起止时间和总用时了,就选了 \(30.721 - 24.579 = 6.123 = 6\)\(D\),但是正解是 \(A\),因为在 Linux 的 time 命令输出中:

  • real:表示程序从开始到结束的实际经过时间(墙钟时间),包括其他进程占用 CPU 的时间和等待时间(如 I/O 等待)。
  • user:表示程序在用户态消耗的 CPU 时间。
  • sys:表示程序在内核态消耗的 CPU 时间。

秒表计时测量的是实际经过时间(real time),因为秒表是从程序开始到结束的物理时间,与 real 时间一致。因此,real 时间 0m30.721s 最接近秒表计时的时长,即约 \(30\) 秒。

Day18 - 周四

这把 2023 真题,前面还好,代码阅读题难到起飞,开始吓蒙,zak 祝我上 60 qwq。 斌斌忘关网了,把周一到周三的记录补了,学习记录回家写,主要记录错题。

zak 的祝福留给正式比赛了,53.5 pts,qwq

今天集团联考(whk),非常猎奇,语英历政,全文科,得吃了。语文阅读挂飞,英语作文标题看不懂乱写,历史小论文两个道路漏一个,政治裸考友好估计 60 pts…… 一切都在预料之中 qwq,老师是这么解释的,集团没有通知具体难度,所以应该会出很难,大家做好心理准备,尽力而为。但是,我们每个老师都善良地给每个学生安排了一个期望分数,班主任要求少一分做 10 个俯卧撑……成绩出后的一周后,你们将见到拥有八块腹肌的 LX。

在快下播时出了问题,免费送我们的大巴没了,听说是学校质量极差的大巴挂了 qwq,只能自己坐地铁了 awa

被这道题创飞了 qwq,答案构造:

我们逐步放置编号1到11,并记录每根柱子的状态(从底部到顶部)。

柱子1: 空
柱子2: 空
柱子3: 空
柱子4: 空

开始放置:

放1:可以任意放(比如柱子1)。
柱子1: [1]
其他空。

放2:需要与1的和为平方数?1+2=3(不是平方)。所以不能放在柱子1上(因为顶部是1)。可以新开柱子2(空柱子无限制)。
柱子1: [1]
柱子2: [2]
其他空。

放3:检查各柱子顶部:

柱子1顶部1: 1+3=4=2²(是平方)→ 可以放柱子1。

柱子2顶部2: 2+3=5(不是平方)→ 不能。

可以新开柱子3。
选择放柱子1(这样链更长?但这里任意)。
柱子1: [1, 3]
柱子2: [2]
柱子3: 空
柱子4: 空

放4:检查顶部:

柱子1顶部3: 3+4=7(不是平方)

柱子2顶部2: 2+4=6(不是平方)

新开柱子4。
柱子4: [4]

放5:检查顶部:

柱子1顶部3: 3+5=8(不是)

柱子2顶部2: 2+5=7(不是)

柱子4顶部4: 4+5=9=3²(是)→ 可以放柱子4。
柱子4: [4,5]

放6:检查顶部:

柱子1顶部3: 3+6=9=3²(是)→ 可以放柱子1。
柱子1: [1,3,6]

放7:检查顶部:

柱子1顶部6: 6+7=13(不是)

柱子2顶部2: 2+7=9=3²(是)→ 放柱子2。
柱子2: [2,7]

放8:检查顶部:

柱子1顶部6: 6+8=14(不是)

柱子2顶部7: 7+8=15(不是)

柱子4顶部5: 5+8=13(不是)

新开?但还有柱子3空?实际上柱子3还是空的(我们只用了3根?但这里柱子3空着)。
但注意:我们已经有4根柱子(但柱子3空),所以可以放柱子3(空柱子无限制)。
柱子3: [8]

放9:检查顶部:

柱子1顶部6: 6+9=15(不是)

柱子2顶部7: 7+9=16=4²(是)→ 放柱子2。
柱子2: [2,7,9]

放10:检查顶部:

柱子1顶部6: 6+10=16=4²(是)→ 放柱子1。
柱子1: [1,3,6,10]

放11:检查顶部:

柱子1顶部10: 10+11=21(不是)

柱子2顶部9: 9+11=20(不是)

柱子3顶部8: 8+11=19(不是)

柱子4顶部5: 5+11=16=4²(是)→ 放柱子4。
柱子4: [4,5,11]

现在,我们已经成功放置了1到11。

尝试放12:
检查各柱子顶部:

柱子1顶部10: 10+12=22(不是平方)

柱子2顶部9: 9+12=21(不是)

柱子3顶部8: 8+12=20(不是)

柱子4顶部11: 11+12=23(不是)

无法放入任何柱子(包括新开?但已经用了4根,没有空柱子了)。因此,12无法放置。

因此,最多放置11个圆环。

忘了染色的概念了 qwq,但二分图肯定是可以的,但是没有二分图,蒙欧拉回路,但是挂,绷。

但是没想到完全三叉树(树)一定没有环(特别是奇数长度的环),所以一定是二分图,一定可以用两种颜色染色 qwq

Day19 - 周五

最后一次模拟,真题干完了(24 年我们都参加了,没必要刷),于是干模拟题,卷子没带,故无法作错题 qwq
晚上回家,得知明天初赛我农历生日,rp 加满 hhh,和斌斌交流好了,可以蹭他的车,快乐。
买了一大袋补给,给 \(A\) 队每人一人一包蒟蒻好吧。

Day20 - 周六(当日初赛)

CSP-J/S 第一轮,信息学竞赛追逐的起点

十年磨一剑 一朝试锋芒,今日便是 CSP 第一轮初赛,我将带着必胜的信念,去迎接眼前的挑战。

清早六点半被摇了起来,吃过早饭匆匆出门,到街边等斌斌的车,手里提着一大袋人情美食。长沙的清晨很冷,寒风吹起帽脚,我不禁捂紧了身上的披着的外衣,顶着风,走下小区门口的楼梯。左手提着重物,双肩背负着背包,迈出右脚。一步,再一步,缓缓走下楼梯,逆着风前行。我站在街边,回首望向北方,等待他的到来。风,依旧吹着,人,依旧站着,依旧等待着。突然,耳边想起奶奶的声音,我恍惚,我不知所措,匆忙转身,原来奶奶带着妹妹来送我了。我说,你们回去吧,这冷,她说没事,我送你。就这样推辞着,关爱着。

突然,耳边传来车笛的鸣叫,啊,他来了。车窗摇下,露出那张亲切的脸。我赶忙打开车门,把那袋心意传达给他,他没说什么,只是叮嘱我,后面的车窗坏了,不要乱动,我知道,我知道。侧首,是奶奶和妹妹在挥手。

车上,风声在呼啸,细微的雨点偶然打在车窗上,身体颠簸着。上高速了,车子逐渐平稳,我的眼皮逐渐沉重,是昨天因紧张没睡好,还是路上车子过于颠簸,我缓缓低下头,埋进怀里,迷迷睡去。

抬头,已经下了高速,斌斌告诉我,快到了,我抓紧身旁的包,昏沉之意全无,目光坚定地望向远方,我知道,我可以的,一定可以的。

来到参赛地点,中雅培粹的门口人头攒动,我与校队的同学会晤,激动地交谈着。大门开了,我们随着人群挤过闸机,不一会儿,各楼考场门前排起长龙,我与 hyx,wzw 蹲坐在长龙旁的草地上,等待长龙消散。hyx 甚至打起了音游,我回想起自己小时候玩钢琴块时笨拙的样子,如今那双钢琴块都点不着的手,已经放到了键盘上,快速地敲击着。我坐在他旁边,看他灵巧的双手在手机屏幕上快速划动,周围的声音很嘈杂,但我依旧听得到零星一点的美妙旋律……

龙尾已经消散,我们进了各自的考场,室外的寒风让我着了凉,还好,我来得比较早,离开考的时间足够我解手了。

处理妥当之后,我走进考场,经过安检之后坐到了自己的位置上。整理好自己的文具,仔细核对好个人信息,小心地在答题卡上完善了个人信息。开考铃响起之际,准备工作已然完备,我提笔,看题。J 组的题很简单,而且今年的题型有所不同,没有背诵题,都是逻辑思维题。如今的 CSP 初赛,已然从半文半理完全转变为理科了,这对于我无疑是巨大的优势。但复杂的计算与模拟依旧让我难以招架,经过了一小时的奋斗,我终于完成了第一大题。距离考试结束还有一小时,还有两大题,但 J 组的程序阅读题还是比较简单的,我轻松地在 40 分钟内完成了所有题目。

让我映像尤深的是完善程序最后一题,那是一道交互题,也是我有点无法理解的题,不过还好,靠感觉写出的五道题只有一道题出了问题。之后回家我查了一下,这竟是 AT 的一道黑题!不过现在想来,对于初赛,还能与之过上几招。我相信,再修行几年,我也可以将黑题斩与马下。

出了考场,找了同学对了一下答案,发现我们的答案差别还是很大的,由于下午还要考试,为了稳定心态,我们停止了对答案。出来后,我与斌斌一同蹭上了 czh 一家的饭,菜肴很丰盛,我们边吃边畅聊 OI,聊生活,聊学习。斌斌还向我描述了他当年的体育是多么地强盛,我们笑,他也笑。

中午休整的时光是短暂的,我们马上回到了考场,斌斌因为下午有事就提前回去了。临走前,他还担心我,问我考完如何回去,我答,坐地铁,他应,路长,小心。门开,我们进,再次坐在长龙旁,我们开了瓶咖啡,分了蒟蒻果冻,为我们下午真正重要的比赛加油。进考场,再次坐下,目光犀利,这次,我不会输。

和上午一样,把考前准备打理妥当,开考铃响,提笔,为梦而战。这次 S 组的题型改得最明显,所有的背诵题改成了算法理念题,对于我这个扎扎实实系统性学完整个提高组的 oier,不在话下。笔一挥,半小时完成第一大题,竟比 J 还顺,可能是计算量小些罢,其中一道容斥的组合计数题我算错了,扣了 2 分。

然后便是程序理解题,第一小题的代码较为简洁,思路明了,模拟起来也不难,我轻松地完成了它。紧接着看第二题,第二题较为复杂,看是模拟,与数学沾点边。我数学不太好,所以整个阅读程序错的 4.5 分就在这里。至于第三题,虽然较第二题更为复杂,但题目的答案很好想,所以在严格的计算后,我完成此题。

最后 40 分钟,我开了第三大题,完善程序。第一题较为简单,我快速解决了它,然后重点围攻第二题。第二题也就是整张试卷最难的题,我仔细分析代码思路,理解题目大意,但是依旧错了两题,扣了完善程序的这 6 分。

最终的总分是 87.5,算是较高的了,可能会有个三到六分的误差,但 80 分应该是上了的,初赛也是可以过的。不过队里的成绩普遍不理想,希望没有人被筛掉吧。

回去了,拿手机导航走了半个小时找到了地铁站,在地铁上对答案,J 组的分数比较惨淡,80 分,可能更低,民间的答案通常有三到六分的误差,这样的分数对于湖南这个较强省还是比较悬的,希望不要出事吧。

一天的奔波的疲惫,我的大脑昏沉,倒在沙发之上,眼前,是一周下来拖欠的作业。明天就将返校,母亲长叹一声,递过笔,为我摆上了台灯……

最后,致敬所有在寒风中赶考、在台灯下刷题的 oiers:

愿你们的努力不被辜负,愿你们的代码永无 BUG,愿你们在复赛赛场斩获佳绩,奔向更远的星辰大海。

你,终将抵达你想去的地方。———— 一个在台灯下奋笔疾书的 oier

posted @ 2025-09-11 22:33  雨落潇湘夜  阅读(8)  评论(0)    收藏  举报
我的页脚图片