【2021夏纪中游记】2021.8.16模拟赛

比赛概括:

\(\mathrm{sum}=25+0+0+0\)

换组别了爆零我真开心。

T1 [USACO21FEB] No Time to Dry P:

题目大意:

【2021夏纪中游记】2021.8.16模拟赛

思路:

莫队,并用线段树求出一个点左右与其相同的点的位置。

代码:

const int N = 2e5 + 10;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n, q, S;
struct Question
{
	int l, r, x, id;
	bool operator < (const Question &a) const
	{
		return x < a.x || (x == a.x && r < a.r);
	}
}b[N];
int a[N], Ans[N], lst[N];
int v[N], L[N], R[N];

struct SegmentTree
{
	struct Tree
	{
		int l, r, val, lzy;
	}t[N << 2];
	void Build(int p, int l, int r)
	{
		t[p].l = l, t[p].r = r, t[p].lzy = -1;
		if (l == r) {t[p].val = a[l]; return;} 
		int mid = l + r >> 1;
		Build (p << 1, l, mid);
		Build (p << 1 | 1, mid + 1, r);
		t[p].val = min(t[p << 1].val, t[p << 1 | 1].val);
	}
		
	int Query(int p, int l, int r)
	{
		if (t[p].r < l || r < t[p].l) return 1e9;
		if (l <= t[p].l && t[p].r <= r) return t[p].val;
		int ans = 0;
		ans = min(Query(p << 1, l, r), Query(p << 1 | 1, l, r)); 
		return ans;
	}
}t;

int main()
{
	n = Read(), q = Read();
	S = 450;
	for (int i = 1; i <= n; i++)
		a[i] = Read();
	for (int i = 1; i <= q; i++)
		b[i].l = Read(), b[i].r = Read(), b[i].x = b[i].l / S + 1, b[i].id = i;
	sort (b + 1, b + 1 + q);
	t.Build(1, 1, n);
	for (int i = 1; i <= n; lst[a[i]] = i, i++)
		if (lst[a[i]]) L[i] = t.Query(1, lst[a[i]], i) < a[i]? -1: lst[a[i]];
		else L[i] = -1;
	memset (lst, 0, sizeof lst);
	for (int i = n; i; lst[a[i]] = i, i--)
		if (lst[a[i]]) R[i] = t.Query(1, i, lst[a[i]]) < a[i]? n + 5: lst[a[i]];
		else R[i] = n + 5;
	
	for (int i = 1, tl = 1, tr = 0, ans = 0; i <= q; i++)
	{
		int l = b[i].l, r = b[i].r;
		while (tl > l) tl--, ans += R[tl] > tr;
		while (tl < l) ans -= R[tl] > tr, tl++;
		while (tr < r) tr++, ans += L[tr] < tl;
		while (tr > r) ans -= L[tr] < tl, tr--;
		Ans[b[i].id] = ans; 
	}
	
//	for (int i = 1; i <= n; i++)
//		printf ("%d %d\n", L[i], R[i]);
	for (int i = 1; i <= q; i++)
		printf ("%d\n", Ans[i]);
	return 0;
}

T2 [USACO21FEB] Minimizing Edges P:

题目大意:

【2021夏纪中游记】2021.8.16模拟赛

思路:

不会。

T3 [USACO21FEB] Counting Graphs P:

题目大意:

【2021夏纪中游记】2021.8.16模拟赛

思路:

不会。

T4 Count the Cows G:

题目大意:

【2021夏纪中游记】2021.8.16模拟赛

思路:

可以发现,图形其实是 “x” 型的分型图,那么分类讨论倍增即可。

calc(v,n) 表示函数 \(y=-x+v\) 图像经过的一的个数。

query(x,y,n) 表示 \((0,0)\) 到 \((x,y)\) 的一的个数。

代码:

const int N = 50;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

unsigned ll x, y, d;
unsigned ll pw[N];
int a[3][3] = {{1, 0, 1}, {0, 2, 0}, {1, 0, 3}};

ll calc (ll v, ll n)
{
	if (n == 1) return 1;
	if (n == 3)
	{
		if(v == 0) return 3;
		if(v == 1) return 0;
		return 1;
	}
	ll m = n / 3;
	if (v < m) return 3ll * calc(v, m);
	if (v == m) return 0;
	if (v < 2ll * m) return calc(2ll * m - v, m);
	return calc (v - 2ll * m, m);
}

ll query(ll x, ll y, ll n)
{
	if (n == 3) return a[x][y];
	if (x > y) x ^= y ^= x ^= y;
	ll v = y - x, m = n / 3ll;
	ll tmp = calc(v, m);
	if (v < m)
	{
		if (y < m) return query(x, y, m);
		if (x < m) return tmp;
		if (y < 2ll * m) return tmp + query(x - m, y - m, m);
		if (x < 2ll * m) return 2ll * tmp;
		return 2ll * tmp + query(x - 2ll * m, y - 2ll * m, m);
	}
	if (v == m) return 0;
	if (v < 2ll * m)
	{
		if (y < 2ll * m) return 0;
		if (x >= m) return calc(2ll * m - v, m);
		return query(x, y - 2ll * m, m);
	}
	return query(x, y - 2ll * m, m);
}

ll Query(ll x, ll y)
{
	if (x < 0 || y < 0) return 0;
	if (x > y) x ^= y ^= x ^= y;
	ll v = y - x;
	int k = upper_bound(pw, pw + 41, y) - pw;
	return query(x, y, pw[k]);
}

int main()
{
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	pw[0] = 1;
	for (int i = 1; i <= 40; i++) pw[i] = pw[i - 1] * 3;
	for (int t = Read(); t--; )
	{
		d = Read(), x = Read(), y = Read();
		printf ("%lld\n", Query(x + d, y + d) - Query(x - 1, y - 1));
	}
	return 0;
}
上一篇:2021-10-21


下一篇:Triton:openai开源GPU编程神器