2023冲刺国赛模拟9

A. 哈密顿路

考虑哈密顿路一定经过 \(1\), 那么在这里断开

\(f_s\) 表示已经走过的点集为 \(s\), 能作为最后一个点出现的点的集合

然后拼起来即可

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int maxn = 24;
char s[maxn + 5];
int n, e[1 << maxn], f[1 << maxn], ans[maxn];
int main(){
	freopen("hamilton.in","r",stdin);
	freopen("hamilton.out","w",stdout);
	n = read();
	for(int i = 0; i < n; ++i){
		scanf("%s",s);
		for(int j = 0; j < n; ++j)if(s[j] == '1')e[1 << i] |= 1 << j;
	}
	for(int s = 1; s < (1 << n); ++s)e[s] = e[s & -s] | e[s ^ (s & -s)];
	f[1] = 1;
	for(int s = 1; s < (1 << n); s += 2)
		for(int i = 0; i < n; ++i)if(!(s >> i & 1) && (e[f[s]] >> i & 1))
			f[s | (1 << i)] |= (1 << i);
	for(int s = 1; s < (1 << n); s += 2){
		int t = (((1 << n) - 1) ^ s) | 1;
		for(int i = 0; i < n; ++i)if(f[s] >> i & 1)ans[i] |= f[t];
	}
	ans[0] = f[(1 << n) - 1];
	for(int i = 0; i < n; ++i, printf("\n"))
		for(int j = 0; j < n; ++j)
			printf("%d",(ans[i] >> j & 1));
	return 0;
}

B. 统一省选

一个区间一定能写成分三段的函数

\((-\infty, a) \to -\infty\)

\([a, b) \to c\)

\((b, \infty) \to (b, \infty) + d\)

线段树维护即可。。。

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, int> pli;

ll read(){
	ll x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int maxn = 1e6 + 55;
const ll inf = 1e14;
ll n, q, h0;

struct node{
	ll a, b, cov, dt;
	void init(int type, ll val){
		if(type == 1)a = val + 1, b = val + 1, cov = 1, dt = -val;
		if(type == 2)a = val, b = inf, cov = a, dt = -inf;
		if(type == 3)a = 1, b = val, cov = val, dt = 0;
	}
	ll trans(ll val){
		if(val >= b)return val + dt;
		if(val >= a)return cov;
		return -inf;
	}
	friend node operator + (const node &x, const node &y){
		if(y.a <= x.cov){
			if(y.b <= x.cov)return {x.a, x.b, x.cov + y.dt, x.dt + y.dt};
			return {x.a, y.b - x.dt, y.cov, x.dt + y.dt};
		}else return {y.a - x.dt, y.b - x.dt, y.cov, x.dt + y.dt};
	}
};
struct seg{
	node t[maxn << 2 | 1];
	void build(int x, int l, int r){
		if(l == r){int type = read(); t[x].init(type, read()); return;}
		int mid = (l + r) >> 1;
		build(x << 1, l, mid);
		build(x << 1 | 1, mid + 1, r);
		t[x] = t[x << 1] + t[x << 1 | 1];
	}
	void modify(int x, int l, int r, int pos){
		if(l == r){int type = read(); t[x].init(type, read()); return;}
		int mid = (l + r) >> 1;
		if(pos <= mid)modify(x << 1, l, mid, pos);
		else modify(x << 1 | 1, mid + 1, r, pos);
		t[x] = t[x << 1] + t[x << 1 | 1];
	}
	pli query(int x, int l, int r, int L, int R, ll val){
		if(l == r){
			if(t[x].trans(val) > 0)return pli(t[x].trans(val), l);
			return pli(-1, l - 1);
		}
		int mid = (l + r) >> 1;
		if(L > mid)return query(x << 1 | 1, mid + 1, r, L, R, val);
		if(L <= l && r <= R && t[x].trans(val) > 0)return pli(t[x].trans(val), r);
		pli res = query(x << 1, l, mid, L, R, val);
		if(res.first == -1)return res;
		return query(x << 1 | 1, mid + 1, r, L, R, res.first);
	}
}T;
int main(){
	freopen("bad.in","r",stdin);
	freopen("bad.out","w",stdout);
	n = read(), q = read(); h0 = read();
	T.build(1, 1, n);
	for(int i = 1; i <= q; ++i){
		int op = read(), x = read();
		if(op & 1)T.modify(1, 1, n, x);
		else{
			pli res = T.query(1, 1, n, x, n, h0);
			if(res.second >= x)printf("%d\n",res.second);
			else printf("-1\n");
		}
	}
	return 0;
}

C. 并行计算

经过一堆证明得到答案为 \(0.4n+O(1)\)

构造 \(16\) 个 用 \(6\) 歩消去 \(15\)

\(11\) 个 用 \(4\) 歩消去 \(10\)

再加上 \(8\)\(3\) 歩消 \(7\)

等边角料处理即可

由于数据已知,所以情况写的不全

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
struct data{
	int a, b;
};
struct node{
	data a[4];
};
vector<node>ans;
void solve16_6(int p0){
	node tmp;
	tmp.a[0] = {p0 + 1, p0 + 2}; tmp.a[1] = {p0 + 4, p0 + 5}; tmp.a[2] = {p0 + 7, p0 + 8}; tmp.a[3] = {p0 + 10, p0 + 11}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 2, p0 + 3}; tmp.a[1] = {p0 + 5, p0 + 6}; tmp.a[2] = {p0 + 8, p0 + 9}; tmp.a[3] = {p0 + 11, p0 + 12}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 3, p0 + 4}; tmp.a[1] = {p0 + 3, p0 + 5}; tmp.a[2] = {p0 + 3, p0 + 6}; tmp.a[3] = {p0 + 13, p0 + 14}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 6, p0 + 7}; tmp.a[1] = {p0 + 6, p0 + 8}; tmp.a[2] = {p0 + 6, p0 + 9}; tmp.a[3] = {p0 + 14, p0 + 15}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 9, p0 + 10}; tmp.a[1] = {p0 + 9, p0 + 11}; tmp.a[2] = {p0 + 9, p0 + 12}; tmp.a[3] = {p0 + 15, p0 + 16}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 12, p0 + 13}; tmp.a[1] = {p0 + 12, p0 + 14}; tmp.a[2] = {p0 + 12, p0 + 15}; tmp.a[3] = {p0 + 12, p0 + 16}; ans.push_back(tmp);
}
void solve11_4(int p0){
	node tmp;
	tmp.a[0] = {p0 + 1, p0 + 2}; tmp.a[1] = {p0 + 3, p0 + 4}; tmp.a[2] = {p0 + 5, p0 + 6}; tmp.a[3] = {p0 + 8, p0 + 9}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 2, p0 + 3}; tmp.a[1] = {p0 + 2, p0 + 4}; tmp.a[2] = {p0 + 6, p0 + 7}; tmp.a[3] = {p0 + 9, p0 + 10}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 4, p0 + 5}; tmp.a[1] = {p0 + 4, p0 + 6}; tmp.a[2] = {p0 + 4, p0 + 7}; tmp.a[3] = {p0 + 10, p0 + 11}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 7, p0 + 8}; tmp.a[1] = {p0 + 7, p0 + 9}; tmp.a[2] = {p0 + 7, p0 + 10}; tmp.a[3] = {p0 + 7, p0 + 11}; ans.push_back(tmp);
}
void solve8_3(int p0){
	node tmp;
	tmp.a[0] = {p0 + 1, p0 + 2}; tmp.a[1] = {p0 + 3, p0 + 4}; tmp.a[2] = {p0 + 5, p0 + 6}; tmp.a[3] = {p0 + 7, p0 + 8}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 2, p0 + 3}; tmp.a[1] = {p0 + 2, p0 + 4}; tmp.a[2] = {p0 + 6, p0 + 7}; tmp.a[3] = {p0 + 6, p0 + 8}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 4, p0 + 5}; tmp.a[1] = {p0 + 4, p0 + 6}; tmp.a[2] = {p0 + 4, p0 + 7}; tmp.a[3] = {p0 + 4, p0 + 8}; ans.push_back(tmp);
}
void solve4_2(int p0){
	node tmp; 
	tmp.a[0] = {p0 + 1, p0 + 2}; tmp.a[1] = {p0 + 3, p0 + 4}; tmp.a[2] = {2000, 2000}; tmp.a[3] = {2000, 2000}; ans.push_back(tmp);
	tmp.a[0] = {p0 + 2, p0 + 3}; tmp.a[1] = {p0 + 2, p0 + 4}; tmp.a[2] = {2000, 2000}; tmp.a[3] = {2000, 2000}; ans.push_back(tmp);
}
void print(){
	printf("%d\n",(int)ans.size());
	for(node v : ans){
		for(int i = 0; i < 4; ++i)printf("%d %d %d ",v.a[i].b, v.a[i].a, v.a[i].b);
		printf("\n");
	}
}
int main(){
	freopen("computer.in","r",stdin);
	freopen("computer.out","w",stdout);
	int n = read();
	int i = 0;
	for(i = 0; i + 16 <= n; i += 15)solve16_6(i);
	switch(n - i){
		case 1 : break;
		case 4 : solve4_2(i); break;
		case 8 : solve8_3(i); break;
		case 9: case 10 : solve11_4(i); break;
		case 14 : solve16_6(i); break;
		case 6 : for(int c = 1; c <= 6; ++c)ans.pop_back(); i -= 15; solve11_4(i); i += 10; solve11_4(i); break;
	}
	print();
	return 0;
}
posted @ 2023-05-31 19:46  Chen_jr  阅读(20)  评论(0编辑  收藏  举报