0%

思路讲解

遇到这种题目不要慌,首先不难发现是线性基。

接着我们不要一下子想特别复杂的情况,我们就想一想 K=2 的时候是怎么样的?

// 因为两段不同的段,相互遮盖的长度是一样的。
    // 奇数加奇数是偶数,偶数加偶数还是偶数
    // 遮盖以后都是加减偶数,并不会影响段的长度的奇偶性。

    这里用到了一个小技巧

就是这个我们知道,如果说我们只要求偶数长度子序列的
        异或最大值怎么办呢?
        这个时候可以给加入线性基的数字加一个标记,如果最后这个值有标记
        就说明是奇数长度子序列得到的和
        否则就是偶数长度子序列得到的和。

AC代码

https://www.codechef.com/viewsolution/1190285113

心路历程(WA,TLE,MLE……)

思路讲解

其他都想到了,就是这个

reverse(all(wp));

需要hack数据才能想到。

其实1 1 之间不会相互影响,但是0 0之间会,把最重要的放在最远,避免互相影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	FOR(i,1,N){
// if(s[i]=='1') A[i]=i-1;
// else A[i]=N;
ll t=N;
if(s[i]=='1'){
t=i-1;
A.PB(t);
reverse(all(wp));
for(auto w:wp){
A.PB(w);
}
wp.clear();
}else{
t=i-1;
wp.PB(t);
}
}

AC代码

https://www.codechef.com/viewsolution/1189976308

心路历程(WA,TLE,MLE……)

思路讲解

Codeforces Round 1048 (Div. 2)——E1. Maple and Tree Beauty (Easy Version)(背包问题)(子集枚举→能否凑出某个的和)

不难发现,用背包会TLE。

说实话,这个就真没招了,看题解吧。

其实用bitset 优化一下就能过去。

最后发现,我这样分一个if else 的反而更快

还有一种曲线救国方法。使用模板参数。

1
2
3
4
5
6
7
template <int maxn>
inline void __() {
// cin >> N >> K;
if (maxn <= N) {
__< min(maxn * 2, (int)MAXN) >();
return;
}

AC代码

https://codeforces.com/contest/2139/submission/337943651

O(N2/w)O(N^2/w) 的时间复杂度,能够过去。

心路历程(WA,TLE,MLE……)

思路讲解

https://chatgpt.com/share/68c0ff99-20d0-8013-b16a-26d60768748a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 我们会发现,能否通过前K关(构造出K前缀),和这个顺序是没有关系的
// 我们直接看前 K 个物品是否可以凑出一个和
// vector<vii> dp(SZ(ls)+5,vii(N+5));
vii dp(N+5);
ll sum=0;
ll ans=0;
// 滚动数组优化,第i层哪些值是可以达到的
dp[0]=true;
FOR(i,1,desti){
ll w=ls[i];
sum+=w;
// 滚动数组反向遍历
ROF(j,N-w,0){
dp[w+j]|=dp[j];
}
FOR(a,0,N){
if(dp[a]){
ll b=sum-a;
if((a<=K && b<=N-K) || (b<=K && a<=N-K) ){
ans=i;
break;
}
}
}
if(ans!=i){
break;
}
}

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

注意,不能直接跑分层图,会TLE。

那怎么办呢?可以用传送门,先确定一些种子节点,再跑多源最短路。

一个比较重要的剪枝其实在这里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FOR(j, 1, N) {
Dis[i][j] = Dis[i - 1][j];
}
priority_queue < DIS > pq;
FOR(u, 1, N) {
for (auto &v : jie[u]) {
Dis[i][u] = min(Dis[i - 1][v], Dis[i][u]);
}
}
FOR(u, 1, N) {
// 超了,或者和原来一样,就不要了
if (Dis[i][u] != Dis[i - 1][u]) {
pq.push({Dis[i][u], u});
}
}

AC代码

914ms,在dij中算跑的很快的。

https://qoj.ac/submission/1310755

心路历程(WA,TLE,MLE……)