HGOI 20200731

7月的最后一天!

不得不说这套题部分分是真的多

T1 马里奥

二分+BFS

没有技术含量

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second

const int N = 1010 ;

int n, m, ex, ey, ans ;
int a[N][N], vis[N][N] ;
queue <pair<int, int> > q ;

bool check(int stp) {
//	cout << stp << endl ;
	memset(vis, 0, sizeof(vis)) ; 
	while (!q.empty()) q.pop() ;
	q.push(mp(n, 1)) ; vis[n][1] = 1 ;
	while (!q.empty()) {
		int x = q.front().fi, y = q.front().se ; q.pop() ;
	//	cout << " * " << x << " " << y << endl ;
		if (x == ex && y == ey) return true ;
		if (y - 1 > 0 && !vis[x][y - 1] && a[x][y - 1]) {
			vis[x][y - 1] = 1 ;
			q.push(mp(x, y - 1)) ;
		}
		if (y + 1 <= m && !vis[x][y + 1] && a[x][y + 1]) {
			vis[x][y + 1] = 1 ;
			q.push(mp(x, y + 1)) ;
		}
		rep(k, 1, stp) {
			if (x - k > 0 && !vis[x - k][y] && a[x - k][y]) {
				vis[x - k][y] = 1 ;
				q.push(mp(x - k, y)) ;
			}
			if (x + k <= n && !vis[x + k][y] && a[x + k][y]) {
				vis[x + k][y] = 1 ;
				q.push(mp(x + k, y)) ;
			}
		}
	}
	return false ;
}

signed main() {
	freopen("mario.in", "r", stdin) ;
	freopen("mario.out", "w", stdout) ;
	scanf("%d%d", &n, &m) ;
	rep(i, 1, n) {
		string s ; cin >> s ;
		rep(j, 1, m) a[i][j] = (s[j - 1] == '#' ? 1 : 0) ;
	}
//	rep(i, 1, n) {
//		rep(j, 1, m) cout << a[i][j] ;
//		cout << endl ;
//	}
	scanf("%d%d", &ex, &ey) ;
	int l = 0, r = n ;
	while (l <= r) {
//		cout << l << " " << r << endl ;
		int mid = (l + r) >> 1 ;
		if (check(mid)) ans = mid, r = mid - 1 ;
		else l = mid + 1 ;
	}
	printf("%d\n", ans) ;
 	return 0 ;
}

T2 祭司

可以发现

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second

const int N = 210 ;
const int iinf = 0x3f3f3f3f ;

struct rec {
    int l, r ; 
} a[N] ;

int n ;
bool f[N * N] ;

signed main() {
	scanf("%d", &n) ;
	int Sum1 = 0, Sum2 = 0 ;
	rep(i, 1, n) {
		scanf("%d%d", &a[i].l, &a[i].r) ;
		Sum1 += a[i].l ; Sum2 += a[i].r ;
	}
	memset(f, 0, sizeof(f)) ;
    f[0] = 1 ;
    rep(i, 1, n)
    per(j, 40000, a[i].l + a[i].r)
    f[j] |= f[j - a[i].l - a[i].r] ;
    int ans = iinf ;
    rep(i, 0, 40000) {
    	if (!f[i]) continue ;
    	ans = min(ans, max(abs(Sum1 - i), abs(Sum2 - i))) ;
	}
    printf("%d\n", ans) ;
    return 0;
}

T3 AK

分块

发现一个数进行一些平方后就会不变,大约进行30次左右

这样就可以暴力

那些操作了过多次的就不管

对后面的进行修改即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second

const int lim = 30 ;
const int N = 66010 ;
const int mod = 2305843008676823040 ;

int n, m, num, len ;
int a[N], bl[N], l[N], r[N], sum[N], cnt[N], fa[N] ;

int mul(int a, int b) {
	int res = 0 ;
	while (b) {
		if (b & 1) res = (res + a) % mod ;
		a = (a << 1) % mod ;
		b >>= 1 ;
	}
	return res % mod ;
}

void build() {
	len = sqrt(n) ;
	num = (n - 1) / len + 1 ;
	rep(i, 1, n) bl[i] = (i - 1) / len + 1 ;
	rep(i, 1, num) l[i] = len * (i - 1) + 1, r[i] = len * i ;
	r[num] = n ;
	rep(i, 1, n) sum[bl[i]] = (sum[bl[i]] + a[i]) % mod ;  
	memset(cnt, 0, sizeof(cnt)) ;
}

int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]) ;
}

int query(int ql, int qr) {
	int L = bl[ql], R = bl[qr], ans = 0 ;
	if (L == R) {
		rep(i, ql, qr) ans = (ans + a[i]) % mod ;
		return ans ;
	} else {
		rep(i, ql, r[bl[ql]]) ans = (ans + a[i]) % mod ;
		rep(i, bl[ql] + 1, bl[qr] - 1) ans = (ans + sum[i]) % mod ;
		rep(i, l[bl[qr]], qr) ans = (ans + a[i]) % mod ;
		return ans ;
	}
}

void update(int ql, int qr) {
	for (int i = ql; i <= qr; i = find(i + 1)) {
		if (i > qr) break ;
		cnt[i]++ ;
		sum[bl[i]] = (sum[bl[i]] - a[i] + mod) % mod ;
		a[i] = mul(a[i], a[i]) % mod ;
		sum[bl[i]] = (sum[bl[i]] + a[i]) % mod ; 
		if (cnt[i] > lim) fa[i] = find(i + 1) ;
	}
}

signed main() {
	freopen("ak.in", "r", stdin) ;
	freopen("ak.out", "w", stdout) ; 
	scanf("%lld%lld", &n, &m) ;
	rep(i, 1, n) scanf("%lld", &a[i]) ;
	build() ;
	rep(i, 1, n + 1) fa[i] = i ;
	while (m--) {
		int ql, qr ; scanf("%lld%lld", &ql, &qr) ;
		printf("%lld\n", query(ql, qr)) ;
		update(ql, qr) ;
	}
	
	return 0 ;
}

posted @ 2020-07-31 07:56  harryhqg  阅读(105)  评论(0编辑  收藏  举报