0%

思路讲解

不难发现,题目中的操作,对题目中总值的影响是

Sum=SumAiAiAj=SumAjSum’=Sum\oplus A_i \oplus A_i \oplus A_j = Sum\oplus A_j

那么如果把两次操作全部选出来。

Sum=SumAj1Aj2Sum‘=Sum\oplus A_{j1} \oplus A_{j2},当然,i1j2i_1≠j_2

i1=j2i_1=j_2,那么就是Sum=SumAj1Ai1Aj1=SumAi1Sum’=Sum\oplus A_{j1} \oplus A_{i1} \oplus A_{j1}=Sum\oplus A_{i1}

那么,这种需要用到01trie树。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// j1,j2
ll ans=0;
FOR(j1,1,N){
ll a=sum^A[j1];
ll mne=tr.argmin_xor(a),mn=tr.min_xor(a);
bool ise=tr.erase(mne);
// 那么 bob 有两种选择,一种是避开我们删除的mne,另一种是就选我们删除的mne
ll lans=min<ll>(tr.min_xor(a),mne^sum);
// 那么删除 mne 可能导致负面影响,那么我们不删除mne的结果是什么那?就是bob选择mne呗
lans=max(lans,mn);
ans=max<ll>(ans,lans);
if(ise) tr.insert(mne);
}
// tr.erase(sum);
// 就是sum^A[i1] 也是一种单独的,虽然上面是又包含,但是是取Max的
ans=min<ll>(ans,tr.max_xor(sum));

AC代码

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

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

思路讲解

其实关键在于这个格子只能走一遍,那么可以建两个dp数组,一个从上面转移过来,一个从下面转移过来。

AC代码

https://www.luogu.com.cn/record/231568236

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

思路讲解

1
2
3
4
5
6
7
8
9
10
11
// 以i为起点,初始值为w,所能够获得的最大收益
vdb dp(N+5);
ROF(i,N,1){
auto [type,val]=A[i];
if(type==1){
dp[i]=max(dp[i+1],dp[i+1]*(1-cost*0.01)+val*W);
}else{
dp[i]=max(dp[i+1],dp[i+1]*(1+grow*0.01)-val*W);
}
}
cout<<fsp(2)<<dp[1]<<"\n";

这道题目,我认为关键点在这里,因此我们推一下

W×val+W×(10.01×cost)×val2+W×(10.01×cost)2×val3W\times val+W\times (1-0.01\times cost)\times val_2 +W\times (1-0.01\times cost)^2\times val_3

不难发现,无论怎么样操作,一个星球的收益一定是一个连乘的式子,因此上述操作就不难理解了。

AC代码

https://vjudge.net/solution/62959677

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

思路讲解

(A[1]++A[len])modM=0(A[1]+\dots+A[len]) \bmod M = 0

(A[2]++A[len+1])modM=0(A[2]+\dots+A[len+1]) \bmod M = 0

(A[1]+A[len+1])modM=0(-A[1]+A[len+1])\bmod M=0

Sumi+LSumi(modM)(i=0,,NL).Sum_{i+L}≡Sum_i(\bmod M)(∀i=0,…,N−L).

https://chatgpt.com/c/68a1e9d2-d4f4-832a-bc89-13ae40f158c5

br 是指的差值的模(模M)。具体来讲,就是 (A[1]+A[len+1])modM=0(-A[1]+A[len+1])\bmod M=0(A[0]+A[len])modM=0(-A[0]+A[len])\bmod M=0 这种位置很多,他们成周期性出现,即是:

b1=A[1]modM=A[len+1]modM=A[2len+1]modMb_1=A[1]\bmod M=A[len+1]\bmod M=A[2len+1]\bmod M \cdots

那么,不难发现,除了要满足传递性,还要满足初始条件,即:

b1+b2++blen0(modM)b_1+b_2​+⋯+b_{len}​≡0 \pmod M

然后可以定义一个dp数组,dp[i][j]dp[i][j] 表示已经选了前 i 个数字,且 sumj(modM)sum\equiv j\pmod M 所需的代价为几(sum=b1+b2++bisum=b_1+b_2+\cdots+b_i)?

为了快速计算这个dp,可以使用一个辅助数组g[i][j]g[i][j] 是指b[i]b[i] 到达b[i]j(modM)b[i]\equiv j \pmod M 所需要的总代价。朴素计算需要O(LMNL)O(MN)O(LM \frac{N}{L}) \Rightarrow O(MN) ( 好像还可以?)

AC代码

https://atcoder.jp/contests/abc419/submissions/68614283

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

题目大意

使得数组趋同,所需要的最少区间加一操作数量。

题目描述

给定 nn 个学生的初始好感度序列 a1,a2,,ana_1, a_2, \dots, a_n
每天可以且必须进行一次操作:选择一个区间 [l,r][l, r] (1lrn1 \le l \le r \le n),将该区间内所有学生的好感度加 1(即对于所有 lirl \le i \le r,执行 ai:=ai+1a_i := a_i + 1)。
求使得最终序列中最多出现 mm 种不同数值所需的最小操作次数(最小天数)。

输入描述

第一行包含一个整数 TT (1T101 \le T \le 10),表示测试数据组数。
对于每组测试数据:
第一行包含两个整数 n,mn, m (1n400,1m21 \le n \le 400, 1 \le m \le 2),分别表示学生数量和允许的最大不同数值种数。
第二行包含 nn 个整数 a1,a2,,ana_1, a_2, \dots, a_n (0ai1000 \le a_i \le 100),表示初始好感度。

输出描述

对于每组测试数据,输出一行一个非负整数,表示所需的最小操作次数。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
输入
4
3 1
3 1 3
5 1
5 1 6 1 8
5 2
5 1 6 1 8
5 2
1 3 2 3 1

输出
2
12
3
1

样例解释

第一组数据 (n=3,m=1n=3, m=1):
初始序列为 [3, 1, 3],目标是让所有数字相同(最多 1 种数值)。

  1. 选择区间 [2,2][2, 2] 进行操作,序列变为 [3, 2, 3]

  2. 再次选择区间 [2,2][2, 2] 进行操作,序列变为 [3, 3, 3]
    共需 2 次操作,序列中只有数值 3,满足条件。

第三组数据 (n=5,m=2n=5, m=2):
初始序列为 [5, 1, 6, 1, 8],目标是让序列中最多只有 2 种不同的数值。
最小需要 3 次操作。

思路讲解

首先我们注意到一件事情,就是这个 M 等于一或者 M 等于二。说白了要么变成同一个数,要么变成两个数。

我是这么感觉的,修改一个数,就是把所有的值修改为最大值。修改两个数其实也简单。修改两个数就是一个最大值,一个次大值,然后把其他的值都修改为次大值就好了。

上面就是我的感觉啊,我们先尝试一下,看看对不对。先尝试手磨一下样例。

不,手磨样例以后,我们发现把所有值修改为最大值,在只修改一个数的时候应该是对的。但是修改两个数的时候,这个情况就比较复杂了。修改两个数的话,我们之前的想法应该是错的。只有一个是对的,就是应该就是先要把这些数,其中的一些数肯定是要变为最大值的,其中的一些数肯定是要变为最大值的。但是至于另外一个值需要怎样取,就比较麻烦了。

OK 啊,偷偷看了一眼题解,这个题解写的还是可以的。比这垃圾 AI 提示写的好。这 AI 提示,我告诉他我的思路,我干脆比不告诉他我的思路还好,写的还好一点。这真的纯纯傻逼,还不如不写。

M 等于一的情况,一种比较方便的实现方法呢,就是直接选择一个极长段,这个极长段中的所有数都比最大值小。不断地选择这样的极长段进行操作,记录一下找不到这个这样子的极长段所需要的操作数量。说白了,这个做法就是一个贪心。