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;
}