2022.10.12———HZOI【CSP-S模拟18】游寄

Preface

排名 Rank27/43

得分 20pts + 11pts + 0pts + 3pts = 34pts

总结:

吃barbar了我靠

T1 赛时把自己 hack 了,但是不会处理 hack 数据

T2 摆烂

T3 高高兴兴二分,高高兴兴伪掉

T4 整了一个假的数据结构,然后发现假了直接打暴力

今天的题是 AGC057A、B 和两道 OpenCup

T1:最长反链,T2:2A+x,T3:No Rest for the Wicked,T4:暴力题

T1 

规律基本都是场上推出来的,在这里大量举例子没啥意义,没找出来规律的自己手模。

需要注意的是高位数的取值。比如说 101110 的比较,首先显然把 10 变成 100,由于 1011 没有到 1999,所以直接取他的前三位和后三位取 max101>011,所以 100101 这一块的也被去掉了,直接取 1021011,答案为 910。场上就是到这里没接着推。挂掉 80pts,囸。但是当时心态确实没了。。

T1
/*hack:
1
10 1011
ans:910
*/
#include <iostream>
#include <cmath>
#define GMY (520 & 1314)
#define char_phi signed
#define re register int
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout)
#define Endl cout << '\n'
#define _ ' '
#define Dl cerr << '\n'
#define DMARK cerr << "###"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}

long long T, L, R, lwei, rwei, final_ans;

inline long long ksm(long long A, long long B){
	long long res(1);
	while (B != 0){
		if ((B & 1) == 1) res = res * A;
		A = A * A;
		B >>= 1;
	}
	return res;
}

void work(){
	cin >> L >> R; lwei = log10(L) + 1, rwei = log10(R) + 1;
	if (lwei == rwei)
		cout << R-L+1 << '\n';
	else {
		lwei = rwei-1; L = MAX(L, ksm(10, lwei-1)+1);
		
		if (R <= ksm(10, rwei-1)*2 - 1)
			cout << R - MAX(L, MAX(R/10, R%ksm(10, rwei-1))+1) + 1 << '\n';
		else 
			cout << R-ksm(10, rwei-1)+1 << '\n';
	}
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	cin >> T;
	while (T --)
		work();
	return GMY;
}

T2 2A+x

简单思考

我们可以把每个数值能够到达的地方都表示为一个区间,比如增加一次的时候区间从 [ai,ai] 扩张为 [2ai,2ai+x],再扩张以此类推。

显然地,对于每个区间,他的数值可以在这个区间内随便去取,我们想要让极差最小,那么答案也就是 maxlminr,考虑每次扩张区间,并实时维护答案。

首先将所有区间都拓展到 max{ai} 附近,然后将区间按照左端点升序右端点降序 sort 一遍。

在外边套一层 while (true)和卡时,内层从1到n依次将每个区间进行一次拓展,因为不一定每次都需要全部区间去进行拓展,所以每有一个区间进行拓展了那就记录一次答案。

在拓展区间时新的 maxl 即为新拓展的区间的左界,直接 O(1) 查询,考虑如何查 minr。将每个区间的右端点扔到线段树中维护最小值,然后每次 Query 一遍即可。

内层时间复杂度是 O(nlogn) 的,配合卡时可以过,AtCoder 也可以过(AtCoder 的时限更大),根据 artalter 的实测发现,只需要全部拓展两次即可出解,也就是 while (true) 和卡时免掉了,外层只需要循环两次。不知道原理是什么。。

因为怕爆 longlong 所以开了 __int128。因为还怕爆 __int128 所以加了一个最大值将要逼近 __int128 的最大限度时就 break。其实也不是最大限度,只有 1034,不过应该足够他出解了。

T2
#include <iostream>
#include <stdarg.h>
#include <algorithm>
#define GMY (520&1314)
#define char_phi signed
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
#define ll __int128
#define int __int128
using namespace std;
// inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NUll), cout.tie(NUll);}
inline ll Max(int cnt, ...){
	va_list tmp; va_start(tmp, cnt); ll rtn = va_arg(tmp, ll), res;
	for (re i = 1 ; i <= cnt-1 ; ++ i)
		res = va_arg(tmp, ll), rtn = MAX(rtn, res);
	va_end(tmp);
	return rtn;
}
inline ll Min(int cnt, ...){
	va_list tmp; va_start(tmp, cnt); ll rtn = va_arg(tmp, ll), res;
	for (re i = 1 ; i <= cnt-1 ; ++ i)
		res = va_arg(tmp, ll), rtn = MIN(rtn, res);
	va_end(tmp);
	return rtn;
}

inline ll read(){
	ll x = 0; char c;
	while (!isdigit(c = getchar()));
	do {x = (x << 3) + (x << 1) + (c & 15);} while (isdigit(c = getchar()));
	return x;
}
void ot(ll x){
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) ot(x/10);
	putchar((x%10)+48);
}

/*
	
*/
const ll LLMX = 1000000000000000000;
const ll DLLMX = 100000000000000000;
const ll conster = DLLMX * DLLMX;

ll n, jia, mx, Up, Down, final_ans;
ll tim;

struct Margin {
	ll l, r;
	friend bool operator < (Margin A, Margin B) {return ((A.l == B.l) ? (A.r < B.r) : (A.l < B.l));}
	inline void CGL () {l <<= 1;}
	inline void CGR () {r <<= 1; r += jia;}
};
struct Segment_Tree {ll mn;};

struct Margin mar[N];
struct Segment_Tree a[N<<2];

#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define mid ((l+r) >> 1)
inline void Pushup(int rt) {a[rt].mn = Min(2, a[lson].mn, a[rson].mn);}
void Build(int rt, int l, int r){
	if (l == r)
		{a[rt].mn = mar[l].r; return ;}
	Build(lson, l, mid);
	Build(rson, mid+1, r);
	Pushup(rt);
}
void Update(int rt, int l, int r, int pos, ll wer){
	if (l == r)
		{a[rt].mn = wer; return ;}
	if (pos <= mid)
		Update(lson, l, mid, pos, wer);
	else 
		Update(rson, mid+1, r, pos, wer);
	Pushup(rt);
}
ll Query(int rt, int l, int r, int L, int R){
	if (L <= l and r <= R)
		return a[rt].mn;
	ll rtn = LLMX * LLMX;
	if (L <= mid)
		rtn = Min(2, rtn, Query(lson, l, mid, L, R));
	if (R > mid)
		rtn = Min(2, rtn, Query(rson, mid+1, r, L, R));
	return rtn;
}
#undef lson
#undef rson
#undef mid

inline void work(){
	n = read(), jia = read();
	ll ai;
	for (re i = 1 ; i <= n ; ++ i)
		{ai = read(); mx = Max(2, mx, ai); mar[i] = (Margin){ai, ai};}
	
	Down = LLMX * LLMX;
	// ot(Down), putchar('\n');
	for (re i = 1 ; i <= n ; ++ i){// 先走到最大值的附近
		while ((mar[i].l << 1) <= mx)
			mar[i].CGL(), mar[i].CGR();
		Up = Max(2, Up, mar[i].l), Down = Min(2, Down, mar[i].r);
	}
	final_ans = Up - Down;
	
	sort(mar+1, mar+n+1);
	Build(1, 1, n);
	
	ll miner1, miner2, res;
	while (true) {
		// ot(mx), putchar('\n');
		if ((clock()-tim) * 1000 >= 800 * CLOCKS_PER_SEC or mx >= conster)
			break;
		for (re i = 1 ; i <= n ; ++ i){
			mar[i].CGL(), mar[i].CGR(); mx = Max(2, mx, mar[i].r);
			Update(1, 1, n, i, mar[i].r);
			
			miner1 = ((i == 1) ? (LLMX * LLMX) : (Query(1, 1, n, 1, i-1)));
			miner2 = ((i == n) ? (LLMX * LLMX) : (Query(1, 1, n, i+1, n)));
			miner1 = Min(2, miner1, miner2);
			
			// cout << "min: "; ot(miner1), putchar('\n');
			// cout << "l: "; ot(mar[i].l), putchar('\n');
			// cout << "判断: "; ot(mar[i].l-miner1), putchar('\n');
			
			final_ans = Min(2, final_ans, ((miner1 <= mar[i].l) ? (mar[i].l-miner1) : (0)));
			
			// cout << "ans: "; ot(final_ans), putchar('\n');
		}
		// Endl; Endl; Endl;
	}
	
	ot(final_ans), putchar('\n');
}
// #define IXINGMY
char_phi main(){
	tim = clock();
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	// Fastio_setup();
	work();
	return GMY;
}

T3 No Rest for the Wicked

没改

T4 (Bruteforce)

别问,贺的陈嘉然

T4
#include <iostream>
#define GMY (520&1314)
#define char_phi signed
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
#define KKK 15
#define mod %
#define P 998244353
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}

/*
	
*/

const int Up = 100000;

int n, K, W, Q, Root, segcnt;
long long z[N];
long long C[KKK][KKK];

struct Segment_Tree {int lson, rson; long long sz; long long f[KKK]; long long cnt[KKK][KKK];};

struct Segment_Tree a[Up<<2];

inline long long ksm(long long A, long long B, long long Per){
	long long res(1);
	while (B != 0){
		if ((B & 1) == 1) res = res * A mod Per;
		A = A * A mod Per;
		B >>= 1;
	}
	return res;
}

#define lson (a[rt].lson)
#define rson (a[rt].rson)
#define mid ((l+r) >> 1)
inline void Pushup(int rt){
	a[rt].sz = a[lson].sz + a[rson].sz;
	
	for (re i = 0 ; i <= W-1 ; ++ i)
		for (re j = 0 ; j <= W-1 ; ++ j)
			a[rt].cnt[i][j] = a[lson].cnt[i][j];
	for (re i = 0 ; i <= W-1 ; ++ i)
		for (re j = 0 ; j <= W-1 ; ++ j)
			a[rt].cnt[i][(j+a[lson].sz) mod W] += a[rson].cnt[i][j];
	
	for (re i = 0 ; i <= K ; ++ i)
		a[rt].f[i] = a[lson].f[i];
	for (re i = 0 ; i <= K ; ++ i){
		long long res(0);
		for (re j = 0 ; j <= i ; ++ j)
			res = (res + a[rson].f[j] * C[i][j] mod P * ksm(a[lson].sz, i-j, P) mod P) mod P;
		a[rt].f[i] = (a[rt].f[i] + res) mod P;
	}
}
void Update(int& rt, int l, int r, int pos, int newone){
	if (rt == 0)
		rt = ++ segcnt;
	if (l == r){
		if (newone == true){
			a[rt].sz ++, a[rt].cnt[l mod W][a[rt].sz mod W] ++;
			for (re i = 0 ; i <= K ; ++ i)
				a[rt].f[i] = (a[rt].f[i] + ksm(a[rt].sz, i, P) * l mod P) mod P;
		}
		else {
			a[rt].cnt[l mod W][a[rt].sz mod W] --;
			for (re i = 0 ; i <= K ; ++ i)
				a[rt].f[i] = (a[rt].f[i] - ksm(a[rt].sz, i, P) * l mod P + P) mod P;
			a[rt].sz --;
		}
		return ;
	}
	if (pos <= mid)
		Update(lson, l, mid, pos, newone);
	else 
		Update(rson, mid+1, r, pos, newone);
	Pushup(rt);
}
inline long long Query(){
	long long res = a[Root].f[K];
	
	for (re i = 0 ; i <= W-1 ; ++ i)
		for (re j = 0 ; j <= W-1 ; ++ j)
			res -= ksm(j, K, W) * i mod W * a[Root].cnt[i][j];
	res = (res + (long long)P*10) mod P;
	return res * ksm(W, P-2, P) mod P;
}
#undef lson
#undef rson
#undef mid

inline void Prework(){
	for (re i = 0 ; i <= 5 ; ++ i){
		C[i][0] = 1;
		for (re j = 1 ; j <= i ; ++ j)
			C[i][j] = C[i-1][j] + C[i-1][j-1];
	}
	for (re i = 1 ; i <= n ; ++ i)
		Update(Root, 0, Up, z[i], true);
}

inline void work(){
	cin >> n >> K >> W;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> z[i];
	
	Prework();
	
	/*for (re i = 0 ; i <= 5 ; ++ i){
		for (re j = 0 ; j <= i ; ++ j)
			cerr << C[i][j] << _;
		Dl;
	}*/
	
	cin >> Q;
	long long pos, wer;
	while (Q --){
		cin >> pos >> wer;
		Update(Root, 0, Up, z[pos], false);
		z[pos] = wer;
		Update(Root, 0, Up, z[pos], true);
		cout << Query() << '\n';
	}
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}
posted @   char_phi  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示