10.5校内模拟赛解题报告

T1

a 是减去 k 的数组, b 是加 k 数组。此时两个数组已经是按照升序排序了,将 b 数组的元素依次填充

到 a 数组中,那么此时的极大值一定是max(a[tot -1],b[i]), 极小值一定是min(b[0],a[i+1]) ,还

有一种可能是本身。

/*
Date:
Source:
konwledge:
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#define orz cout << "AK IOI"
#define int long long

using namespace std;
const int maxn = 1e5 + 10;

inline int read()
{
	int f = 0, x = 0;
	char ch = getchar();
	while(!isdigit(ch)) f |= (ch == '-'), ch = getchar();
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}
inline void print(int X)
{
	if(X < 0)
	{
		X = ~(X - 1);
		putchar('-');
	}
	if(X > 9) print(X / 10);
	putchar(X % 10 + '0');
}
int n, k, ans = 0x3f3f3f3f, a[maxn], tot, vis[maxn], b[maxn];
/*
void dfs(int now)
{
	if(now == tot + 1)
	{
		for(int i = 1; i <= tot; i++) b[i] = a[i];
		sort(a + 1, a + tot + 1);
		ans = min(ans, a[tot] - a[1]);
		for(int i = 1; i <= tot; i++) a[i] = b[i];
		return ;
	}
	if(!vis[now])
	{
		a[now] += k;
		vis[now] = 1;
	}
	dfs(now + 1);
	a[now] -= k, vis[now] = 0;
	a[now] -= k;
	dfs(now + 1);
	a[now] += k;
}
*/
signed main()
{
	n = read(), k = read();
	for(int i = 1; i <= n; i++) a[i] = read();
	sort(a + 1, a + n + 1);
	tot = unique(a + 1, a + n + 1) - a - 1;
	for(int i = 1; i <= tot; i++)
	{
		a[i] -= k;
		b[i] = a[i] + 2 * k;
	}
	ans = a[tot] - a[1];
	for(int i = 1; i <= tot; i++)
		ans = min(ans, max(b[i], a[tot]) - min(b[1], a[i + 1]));
	printf("%lld", ans);
	return 0;
}
/*
4 3
1 5 6 7
*/

T2

(f[i])​ 记录上一个字符是否能被凑出来,用 vector 存这个字符后可以被拼出来的字符,然后 dfs 搜索输出。

字符串hash 的时候,一定要记得 s[i] - 'a' + 1, 一定要 + 1啊!!!

/*
Date:2021.10.5
Source:模拟赛 
knowledge:
*/
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
#define orz cout << "AK IOI" << "
"
#define Min(x, y) ((x) < (y) ? (x) : (y))
#define Max(x, y) ((x) > (y) ? (x) : (y))
#define int long long

using namespace std;
const int maxn = 210;
const int mod = 1e9 + 7;
const int base = 13131;

inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
inline void print(int X)
{
	if(X < 0) X = ~(X - 1), putchar('-');
	if(X > 9) print(X / 10);
	putchar(X % 10 ^ '0');
}
int f[maxn], n, len1, ans[maxn], tot;
char s[maxn], ss[maxn];
map <int, bool> mp;
vector <int> e[maxn];

void dfs(int u, int tot)
{
	ans[tot] = u;
	if(u == len1)
	{
		for(int i = 1; i <= len1; i++)
		{
			cout << s[i];
			if(i != len1)
				for(int j = 1; j <= tot; j++) if(ans[j] == i) printf("_");
		}
		puts("");
		return ;
	}
	for(int i = 0; i < e[u].size(); i++)
	{
		int v = e[u][i];
		dfs(v, tot + 1);
	}
}
signed main()
{ 
	//freopen("ewfc.out","w",stdout);
	scanf("%s", s + 1);
	len1 = strlen(s + 1);
	n = read();
	for(int i = 1; i <= n; i++)
	{
		scanf("%s", ss + 1);
		int res = 0, len = strlen(ss + 1);
		for(int j = 1; j <= len; j++) res = (res * base % mod + ss[j] - 'a' + 1) % mod;
		mp[res] = 1;
	}
	f[0] = 1;
	for(int i = 1; i <= len1; i++)
	{
		for(int j = 1; j <= i; j++)
		{
			if(f[j - 1])
			{
				int res = 0;
				for(int k = j; k <= i; k++) res = (res * base % mod + s[k] - 'a' + 1) % mod;
				if(!mp[res]) continue;
				f[i] = f[i] + f[j - 1];	
				e[j - 1].push_back(i);
			}
		}
	}
	if(f[len1] != 0) dfs(0, 1);
	return 0;
}

T3

价格是一个波动的序列,所以根据贪心的策略,要在最高点卖,最低点买,这样的差是最大的,所以用

树状数组维护区间和,把一个区间里面那些最高点的和和最低点的相反数维护出来。

无情偷代码。

#include<bits/stdc++.h>
using namespace std;
int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if (c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x * f;
}
int n,m;
namespace PT1
{
	const int N=100000+100;
	int a[N],tree1[N],tree2[N],bz1[N],bz2[N],ma[N],nn;
	int lowbit(int x)
	{
		return x&-x;
	}
	void update(int *tree,int pos,int c)
	{
		while(pos<=n)
		{
			tree[pos]+=c;
			pos+=lowbit(pos);
		}
	}
	int query(int *tree,int pos)
	{
		int ret=0;
		while(pos)
		{
			ret+=tree[pos];
			pos-=lowbit(pos);
		}
		return ret;
	}
	void updatep_v(int i)
	{
		if(i<=1||i>=n) return ;
		int tmp=query(tree1,i)-query(tree1,i-1);
		update(tree1,i,-tmp);
		tmp=query(tree2,i)-query(tree2,i-1);
		update(tree2,i,-tmp);
		bz1[i]=0;
		bz2[i]=0;
		if(a[i]>a[i-1]&&a[i]>=a[i+1]) bz1[i]=1,update(tree1,i,a[i]);
		if(a[i]<=a[i-1]&&a[i]<a[i+1]) bz1[i]=-1,update(tree1,i,-a[i]);
		if(a[i]>=a[i-1]&&a[i]>a[i+1]) bz2[i]=1,update(tree2,i,a[i]);
		if(a[i]<a[i-1]&&a[i]<=a[i+1]) bz2[i]=-1,update(tree2,i,-a[i]);
	}
	int main()
	{
		for(int i=1; i<=n; ++i) a[i]=read();
		for(int i=2; i<n; ++i)
		{
			if(a[i]>a[i-1]&&a[i]>=a[i+1]) bz1[i]=1,update(tree1,i,a[i]);
			if(a[i]<=a[i-1]&&a[i]<a[i+1]) bz1[i]=-1,update(tree1,i,-a[i]);
			if(a[i]>=a[i-1]&&a[i]>a[i+1]) bz2[i]=1,update(tree2,i,a[i]);
			if(a[i]<a[i-1]&&a[i]<=a[i+1]) bz2[i]=-1,update(tree2,i,-a[i]);
		}
		while(m--)
		{
			int opt=read();
			if(opt==1)
			{
				int l=read(),r=read();
				if(l==r)
				{
					cout<<0<<'
';
					continue;
				}
				int ans=0;
				if(l<r)
				{
					if(a[l]<a[l+1]) ans-=a[l];
					if(a[r]>a[r-1]) ans+=a[r];
					ans+=query(tree1,r-1)-query(tree1,l);
				}
				else
				{
					swap(l,r);
					if(a[r]<a[r-1]) ans-=a[r];
					if(a[l]>a[l+1]) ans+=a[l];
					ans+=query(tree2,r-1)-query(tree2,l);
				}
				printf("%d
",ans);
			}
			else
			{
				int p=read(),w=read();
				a[p]=w;
				updatep_v(p-1),updatep_v(p),updatep_v(p+1);
			}
		}
		return 0;
	}
}
int main()
{
	n=read(),m=read();
	PT1::main();//100pts
	return 0;
}

原文地址:https://www.cnblogs.com/yangchengcheng/p/15369475.html