复习与回顾:2021. 7 .8 contest 1

复习与回顾:2021.7.8 contest 1

A

Description

? 模拟一款坦克游戏的击穿判定(详细部分 略)

Solution

? 分类讨论+模拟(签到题 详解略)

B

Description

? 给定一个长度为 \(n\)? 的序列 \(a\)? ,给出 \(m\) 个操作。

? 每次操作给出 \(x,y\) 表示将序列中所有的 \(x\) 修改为 \(y\)

? 定义序列中两个元素的距离: \(dis(a_i,a_j) = \begin{cases}|i-j|, & {a_i = a_j} \\inf(INT\_MAX:2147483647), & {a_i \neq a_j}\end{cases}\)????

? 每次操作后求出 \(max_{i \neq j \ \in [1,n]}\left\{dis(a_i , a_j)\right\}\)

Input

? 第一行两个数 \(n,m\)?
? 第二行 \(n\)? 个数,依次表示序列 \(a\)? ?中的每个元素。
? 然后 \(m\) 行每行两个数 \(x\)\(y\) ,表示序列中所有 \(x\) 会变成 \(y\)

Output

? 输出 \(m\) 行,即对于每次修改操作,输出一行一个数表示进行了修改后的答案

Example

input:
5 5
2 7 6 3 8
2 3
6 1
8 1
1 2
2 3
output:
3 3 2 2 1

Hint

? 满足 $1 \leq n,m \leq 10^5 ;,; 1 \leq\ a_i \leq n $?

Solution

? 注意到只有\(a_i\)?相同的前驱、后继才会对答案产生影响,于是利用\(set\)对于每种\(a_i\)???维护位置集合。

? 注意到每次操作后\(a_i\)?的种类数和答案只会减少,于是采用启发式合并的思想,每次操作将\(size\)???小的位置集合中所有元素依次取出并插入到另一集合中,每次插入时查找前驱后继并更新答案。

? 启发式合并均摊复杂度\(O(n\,logn)\)?? ,而每次插入、查找、迭代器迭代的复杂度均为\(O(logn)\)?? ,于是总复杂度\(O(n\;log^2n)\)?

? \(PS\)?.其实按照题意应该特判\(a_i\)?两两不同的情况,或者将Ans变量的初值赋为\(INT\_MAX\)?

Code

(略)

C

Description

? 输入一个01\(S1\) 。你需要输出一个最短的01\(S2\) ,使得 \(S2\)\(S1\) 中从未出现过。
? 如果有多个可行的解,你需要输出字典序最小的那一个。

Input

? 一行一个字符串,表示\(S1\)

Output

? 一行一个字符串,表示\(S2\)

Example

input
10100011
output
110

Hint

? 时限 \(1s\)?

? 满足 \(1 \leq |S1| \leq 16777216\)

Solution

? 容易发现 若\(|S2|=L\)????????????时有解,则 \(\forall L^{‘}\geq L \;,\;\exists S2(|S2|=L^{‘})\)????????是解??。

? 观察数据范围(其实也是提示),发现 \(16777216=2^{24}\)??? 而当 \(|S2|=24,|S1|=1677216\)? 时共有\(1677216\)??种01串可作为\(S2\),却最多只有\(1677193\)种长度为\(24\)01串可作为\(S1\)的子串,根据抽屉原理此时必有一解。

? 于是产生一个想法:暴力枚举\(|S2|\)?,每次\(O(n)\)?????判断并寻找答案。 然而\(|S1|\)?比较大,这样并不能在时限内得出答案。回想起第一段的那句话,发现我们可以改为二分\(|S2|\)?来优化。

Code

(略)

D

Description

? 给定一个序列 \(A\),定义一个区间\([l,r]\)的最大子段和\(f(l,r)=max_{i \leq j \; \in [l,r]}\left\{\sum_{k=i}^{j}{A_i}\right\}\)
? 求出所有 \(1 \leq l \leq r \leq n\) 的区间\([l,r]\)的最大子段和 的和,答案对\(2^{64}\)取模。

Input

? 第一行一个数 \(n\)

? 第二行 \(n\) ?个数,第 \(i\)? 个表示 \(A_i\)

Output

? 一行一个数表示答案。

Example

input 1
5 
1 -1 1 -1 1
output 1
11
input 2
5 
1 -2 3 -4 5
output 2
39

Hint

? 满足 \(1 \leq n \leq 10^5 \ ,\ -10^9 \leq A_i \leq 10^9\)

Solution

? 由于对所有区间求和,考虑线段树分治,于是问题转化为如何求出\(\sum_{i \in [l,mid] \;,\; j \in [mid+1,r]} {f(i,j)}\)

? 设 \(g_l(l,k)=max_{i=l}^{k}\left\{\sum_{j=i}^{k}{A_j}\right\}\) , \(g_r(k,r)=max_{i=k}^{r}\left\{\sum_{j=k}^{i}{A_j}\right\}\)

? 我们知道对于\([l,r]_{l \neq r},f(l,r)=max\left\{f(l,k)\ ,\ g_l(l,k)+g_r(k+1,r)\ ,\ f(k+1,r) \right\}(\ {k \in [l,r)}\ )\)????

? 也就是说\(f(i,j)=max\left\{f(i,mid)\ ,\ g_l(i,mid)+g_r(mid+1,j)\ ,\ f(mid+1,j)\right\}\)??????

? 我们可以枚举\(i\)???计算当 \(f(i,mid) \geq f(mid+1,j)\)??? 时 \(f(i,j)\)??? 的贡献,同理枚举\(j\)???计算当 \(f(i,mid) < f(mid+1,j)\)??? 时 \(f(i,j)\)??? 的贡献

? 具体的,当枚举一个确定的\(i\)?时我们有确定的\(f(i,mid),g_l(i,mid)\)??? ,设此时贡献为\((*)\)?,于是?

\[\exists ! \ p_1=max\left\{\ \ p \in [mid+1,r]\ |\ (\ \forall j \in [mid+1,p] \ ,\ g_l(i,mid)+g_r(mid+1,j) \leq f(i,mid)\ )\ \ \right\}\\exists ! \ p_2=max\left\{\ \ p \in [mid+1,r]\ |\ (\ \forall j \in [mid+1,p] \ ,\ f(mid+1,j) \leq f(i,mid)\ )\ \ \right\} \]

? \(p_1\)\(p_2\)可以通过二分求得

\[\text{if}\ \ p_1 \geq p_2 :\(*)=\sum_{j=mid+1}^{p_2}{f(i,mid)}\ \ =\ \ (p_2-mid)*f(i,mid)\\text{otherwise}:\(*)=\sum_{j=mid+1}^{p_1}{f(i,mid)}\ \ +\sum_{j=p_1+1}^{p_2}{(\ g_l(i,mid)+g_r(mid+1,j)\ )}\=(p_1-mid)*f(i,mid)\ +\ (p_2-p_1)*g_l(i,mid)\ +\ \sum_{j=p_1+1}^{p_2}{g_r(mid+1,j)} \]

? 上式经过类似前缀和的预处理后可\(O(1)\)计算

? 枚举\(j\)时我们也做相似的处理

? 由于线段树分治+二分,总复杂度为\(O(n\,log^2n)\)

Code
long long MS[100005],NS[100005];//MS:gl/gr   NS:f
unsigned long long SM[100005];//前缀和 由于对2^64取模,使用自然溢出
void Solve(int l,int r){
	if(l==r){Ans+=A[r];return;}
	int mid=(l+r)>>1;
	Solve(l,mid);Solve(mid+1,r);
	//开始预处理:
	for(int i=l;i<=r;i++)SM[i]=MS[i]=NS[i]=0;
	SM[mid]=MS[mid]=NS[mid]=A[mid];
	for(long long i=mid-1,Mc=A[mid],Nc=A[mid];i>=l;i--){
		Mc+=A[i];if(MS[i+1]>Mc)MS[i]=MS[i+1];else MS[i]=Mc;SM[i]=SM[i+1]+MS[i];
		(Nc<0?Nc=0:0);Nc+=A[i];if(NS[i+1]>Nc)NS[i]=NS[i+1];else NS[i]=Nc;
	}
	SM[mid+1]=MS[mid+1]=NS[mid+1]=A[mid+1];
	for(long long i=mid+2,Mc=A[mid+1],Nc=A[mid+1];i<=r;i++){
		Mc+=A[i];if(MS[i-1]>Mc)MS[i]=MS[i-1];else MS[i]=Mc;SM[i]=SM[i-1]+MS[i];
		(Nc<0?Nc=0:0);Nc+=A[i];if(NS[i-1]>Nc)NS[i]=NS[i-1];else NS[i]=Nc;
	}
	//结束预处理
	unsigned long long An=Ans,STO=0;
	//枚举i:
	for(int i=mid;i>=l;i--){
		int L=mid+1,R=r,MD,CT;
		long long Mi=MS[i],Ni=NS[i];
		while(L<=R){MD=(L+R)>>1;
			if(NS[MD]<Ni)L=MD+1;else R=MD-1;
		}if(R<=mid)continue;CT=R;//CT==p2
		L=mid+1;while(L<=R){MD=(L+R)>>1;
			if(MS[MD]<Ni-Mi)L=MD+1;else R=MD-1;
		}
		Ans+=1ull*(R-mid)*Ni;
		Ans+=1ull*(CT-R)*Mi+SM[CT]-(R>mid?SM[R]:0);
	}
	//枚举j:
	for(int i=mid+1;i<=r;i++){
		int L=l,R=mid,MD,CT;
		long long Mi=MS[i],Ni=NS[i];
		while(L<=R){MD=(L+R)>>1;
			if(NS[MD]<=Ni)R=MD-1;else L=MD+1;
		}if(L>mid)continue;CT=L;//CT==p2
		R=mid;while(L<=R){MD=(L+R)>>1;
			if(MS[MD]<Ni-Mi)R=MD-1;else L=MD+1;
		}
		Ans+=1ull*(mid-L+1)*Ni;
		Ans+=1ull*(L-CT)*Mi+SM[CT]-(L<=mid?SM[L]:0);
	}
}

复习与回顾:2021. 7 .8 contest 1

上一篇:VSCode 使用


下一篇:样式不显示,静态资源路径错误