解个方程,就 a = b + c a = b + c a=b+c和 s − a = s − b = s − c s - a = s - b = s - c s−a=s−b=s−c
s s s是最后做完操作的每个数, a a a是最小的那个数要补多少,然后接这个方程就行。
#include
#include
int main () {
int a[3];
std::cin >> a[0] >> a[1] >> a[2];
std::sort(a, a + 3);
int s = a[1] + a[2] - a[0];
int ans = 3 * s - a[0] - a[1] - a[2];
std::cout << ans / 2 << '\n';
return 0;
}
贪心
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int const N = 1005;
vector<int> g[N], f[N]; ///f add, g minus
int n, m, s;
int main() {
scanf("%d%d%d", &n, &m, &s);
for (int i = 1; i <= n; ++i) {
int c, x, y;
scanf("%d%d%d", &c, &x, &y);
if (c > 0)
f[y].push_back(c);
if (c < 0)
g[x].push_back(c);
}
bool ans = 0;
for (int i = 1; i <= m; ++i) {
for (auto p : g[i])
s += p;
if (s < 0)
ans = 1;
for (auto p : f[i])
s += p;
}
if (ans)
puts("YES");
else
puts("NO");
}
分块bitset暴力
#include
#include
#include
#include
#include
#include
#include
const int N = 100000;
const int SMALL = 100;
class Set {
std::unique_ptr<std::vector<int>> v;
std::unique_ptr<std::bitset<N>> bs;
Set (std::unique_ptr<std::vector<int>> v_, std::unique_ptr<std::bitset<N>> bs_)
: v(std::move(v_)), bs(std::move(bs_)) {}
void to_bs () {
bs = std::make_unique<std::bitset<N>>(as_bs());
if (v) v = nullptr;
}
public:
Set (): Set(nullptr, nullptr) {}
Set (std::vector<int> v_): Set(std::make_unique<std::vector<int>>(v_), nullptr) {}
Set (Set const &rhs): Set() {
if (rhs.v)
v = std::make_unique<std::vector<int>>(*rhs.v);
if (rhs.bs)
bs = std::make_unique<std::bitset<N>>(*rhs.bs);
}
Set &operator = (Set &&rhs) {
v = std::move(rhs.v);
bs = std::move(rhs.bs);
return *this;
}
int count () const {
if (v) return v->size();
if (bs) return bs->count();
return 0;
}
void clear() {
v = nullptr;
bs = nullptr;
}
std::bitset<N> as_bs () const {
if (bs)
return *bs;
auto ret = std::bitset<N>();
if (v)
for (int x: *v)
ret.set(x);
return ret;
}
void set (int x) {
if (v) {
if (std::find(v->begin(), v->end(), x) == v->end()) {
v->push_back(x);
if (v->size() >= SMALL)
to_bs();
}
} else if (bs)
bs->set(x);
else
v = std::make_unique<std::vector<int>>(1, x);
}
void union_ (Set const &rhs) {
assert(v || bs);
assert(rhs.v || rhs.bs);
if (v && rhs.v && v->size() + rhs.v->size() < SMALL) {
for (int x: *rhs.v)
v->push_back(x);
std::sort(v->begin(), v->end());
v->erase(std::unique(v->begin(), v->end()), v->end());
return;
}
if (!bs)
to_bs();
*bs |= rhs.as_bs();
}
friend std::ostream &operator <<(std::ostream &os, Set const &rhs) {
os << "{ ";
if (rhs.v)
for (int x: *rhs.v)
os << x << ", ";
if (rhs.bs)
for (int i = 0; i < N; ++i)
if ((*rhs.bs)[i])
os << i << ", ";
return os << "}";
}
};
class UnionSet {
mutable std::vector<std::pair<int, int>> v;
public:
UnionSet (int n): v(n) {
for (int i = 0; i < n; ++i)
v[i] = { i, 1 };
}
int find(int x) const {
int f = x;
while (f != v[f].first)
f = v[f].first;
while (x != f) {
int t = v[x].first;
v[x].first = f;
x = t;
}
return f;
}
std::pair<int, int> union_ (int a, int b) {
a = find(a), b = find(b);
if (a == b)
return { -1, -1 };
if (v[a].second < v[b].second)
std::swap(a, b);
v[b].first = a;
v[a].second += v[b].second;
return { a, b };
}
};
int main () {
// freopen("in", "r", stdin);
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
auto blks = UnionSet(n);
std::vector<Set> fs, ts;
for (int i = 0; i < n; ++i){
fs.push_back(Set { {} });
ts.push_back(Set { { i } });
}
for (int i = 0; i < m; ++i) {
int a, b;
scanf("%d%d", &a, &b);
--a, --b;
fs[a].set(b);
fs[b].set(a);
}
for (int i = 0; i < k; ++i) {
int a, b;
scanf("%d%d", &a, &b);
--a, --b;
auto p = blks.union_(a, b);
if (p.first != -1) {
ts[p.first].union_(ts[p.second]);
ts[p.second].clear();
}
}
int q;
scanf("%d", &q);
for (int i = 0; i < q; ++i) {
char cmd[2];
int a, b;
scanf("%s%d", cmd, &a);
// for (int i = 0; i < n; ++i)
// std::cerr << fs[i] << ' ';
// std::cerr << " <
// for (int i = 0; i < n; ++i)
// std::cerr << ts[i] << ' ';
// std::cerr << " <
if (cmd[0] == '?') {
--a;
int ans = (ts[blks.find(a)].as_bs() & fs[a].as_bs()).count();
printf("%d\n", ans);
} else if (cmd[0] == 'T') {
scanf("%d", &b);
--a, --b;
auto p = blks.union_(a, b);
if (p.first != -1) {
ts[p.first].union_(ts[p.second]);
ts[p.second].clear();
}
} else {
scanf("%d", &b);
--a, --b;
fs[a].set(b);
fs[b].set(a);
}
}
return 0;
}
。。。。。
#include
#include
using namespace std;
int random(int l, int r) {
static std::random_device rd;
struct timeb timeSeed;
ftime(&timeSeed);
size_t seed = timeSeed.time * 1000 + timeSeed.millitm; // milli time
static std::mt19937 gen(seed);
std::uniform_int_distribution<> u(l, r);
return u(gen);
}
int const N = 35;
int a[N], x[N];
int n;
long long m = 0;
int ans = 0;
void chk(int t, long long s, bool can) {
if (t >= n) {
if (can)
ans += s % m == 0;
return;
}
for (int i = -1; i <= 1; ++i)
chk(t + 1, s + x[t] * i, can | (i != 0));
}
void rnd() {
static int lim = (1 << 30) - 1;
long long sum = 0;
do {
sum = 0;
for (int i = 0; i < n; ++i) {
x[i] = random(-lim, lim);
sum += a[i] * x[i];
}
} while (sum % m == 0);
}
int main() {
cin >> n;
for (int i = 0; i < n; ++i)
cin >> a[i];
int now = 0;
for (int i = 0; i < n; ++i)
if (a[i] == 0)
x[i] = 1 << (now++);
for (int i = 0; i < n; ++i)
if (a[i] == -1)
x[i] = -(1 <<(now++));
for (int i = 0; i < n; ++i)
if (a[i] == 1)
x[i] = 1 << (now++);
for (int i = 0; i < n; ++i)
m += x[i] * a[i];
cout << m << '\n';
for (int i = 0; i < n; ++i)
cout << x[i] << ' ';
cout << '\n';
/*
ans = 0;
chk(0, 0, 0);
cerr <
}
为什么最短路题才过了这么点呢(指在我们过题的时候
#include
#include
#include
#include
#include
const int N = 8;
int64_t dis[N][N];
void adde (int a, int b, int64_t w) {
dis[a][b] = std::min(dis[a][b], w);
dis[b][a] = std::min(dis[b][a], w);
}
int64_t absll (int64_t x) {
return x >= 0 ? x : -x;
}
void init () {
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
dis[i][j] = std::numeric_limits<int64_t>::max() / 2;
}
int64_t dis2 (int ibeg, int iend) {
for (int k = 0; k < N; ++k)
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
dis[i][j] = std::min(dis[i][j], dis[i][k] + dis[k][j]);
return dis[ibeg][iend];
}
int main () {
int a, b, c, t[3], d, k, i, l, j;
scanf(
"%*d%*d%*d"
"%d%d%d"
"%d%d%d%d"
"%d%d%d%d",
&a, &b, &c,
&t[0], &t[1], &t[2], &d,
&k, &i, &l, &j
);
init();
adde(0, 1, t[0]); // a -- a + 1
adde(2, 3, t[1]); // b -- b + 1
adde(4, 5, t[2]); // c -- c + 1
adde(0, 3, d); // a -- b + 1
adde(2, 5, d); // b -- c + 1
adde(4, 1, d); // c -- a + 1
int ibeg = 6, iend = 7;
auto f = [&](int beg, int iline, int x) {
if (iline == 1) {
adde(beg, 0, t[0] * absll(a - x));
adde(beg, 1, t[0] * absll(a + 1 - x));
} else if (iline == 2) {
adde(beg, 2, t[1] * absll(b - x));
adde(beg, 3, t[1] * absll(b + 1 - x));
} else {
adde(beg, 4, t[2] * absll(c - x));
adde(beg, 5, t[2] * absll(c + 1 - x));
}
};
f(ibeg, k, i);
f(iend, l, j);
if (k == l)
adde(ibeg, iend, t[k - 1] * absll(i - j));
auto ans = dis2(ibeg, iend);
printf("%" PRId64 "\n", ans);
return 0;
}
简单暴力简单开桶?x
#include
#include
#include
#include
using namespace std;
int const N = 25;
int const M = 40000005;
int tot[M];
int f[1 << N];
int a[N];
int n, m;
int dfn[1 << N];
void out_(int st) {
static int ans[N];
int ret = 0;
for (int i = 0; i < n; ++i)
if ((1 << i) & st)
ans[++ret] = i;
cout << ret << '\n';
for (int i = 1; i <= ret; ++i)
cout << ans[i] + 1 << ' ';
cout << '\n';
}
void out_ans(int st1, int st2) {
int uns = st1 & st2;
st1 -= uns;
st2 -= uns;
out_(st1);
out_(st2);
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
dfn[1 << i] = i;
memset(tot, -1, sizeof(tot));
tot[0] = 0;
for (int i = 1, lim = 1 << n; i < lim; ++i) {
f[i] = (f[i - (i & -i)] + a[dfn[i & -i]]) % m;
if (tot[f[i]] != -1) {
out_ans(i, tot[f[i]]);
return 0;
}
tot[f[i]] = i;
}
puts("-1");
}
简单的暴力简单的卡题意?
#include
#include
#include
#include
#include
bool check (
std::string const &ans,
std::string const &a,
std::string const &b
) {
int n = ans.size();
int cnt[4][2] = {};
for (int i = 0; i < n; ++i) {
if (a[i] == ans[i])
++cnt[0][b[i] == a[i]];
else
++cnt[1][b[i] == a[i]];
if (b[i] == ans[i])
++cnt[2][a[i] == b[i]];
else
++cnt[3][a[i] == b[i]];
}
return
cnt[0][1] > cnt[0][0] &&
cnt[1][1] > cnt[1][0] &&
cnt[2][1] > cnt[2][0] &&
cnt[3][1] > cnt[3][0];
}
int main () {
int n;
std::cin >> n;
std::string ans;
std::cin >> ans;
int m;
std::cin >> m;
auto v = std::vector<std::string>(m);
for (auto &s: v)
std::cin >> s;
auto ret = std::vector<std::pair<int, int>>();
for (int i = 0; i < m; ++i)
for (int j = i + 1; j < m; ++j)
if (check(ans, v[i], v[j]))
ret.push_back({ i, j });
std::cout << ret.size() << '\n';
for (auto &p: ret)
std::cout << p.first + 1 << ' ' << p.second + 1 << '\n';
return 0;
}
其实只要建个图,然后每次相邻三个求交就行x
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int const N = 200005;
int a[N][3];
vector<int> G[N];
int ans[N];
map<pair<int, int>, int> mp;
int n;
void addedge(int x, int y) {
G[x].push_back(y);
// cerr << ">> " << x << ' ' << y << '\n';
}
void addedge_solve(int x, int y, int id) {
if (x > y)
swap(x, y);
auto p = make_pair(x, y);
if (mp[p]) {
addedge(mp[p], id);
addedge(id, mp[p]);
} else
mp[p] = id;
}
int get_nxt(int fa, int id) {
for (auto c : G[id]) {
if (c == fa)
continue;
return c;
}
//assert(false);
return -1;
}
bool in_(int id, int x) {
for (int i = 0; i < 3; ++i)
if (x == a[id][i])
return 1;
return 0;
}
bool chk(int x, int y, int id) {
if (x != y && in_(id, x) && in_(id, y))
return 1;
return 0;
}
int find_oth(int id, int x, int y) {
for (int i = 0; i < 3; ++i) {
if (a[id][i] == x || a[id][i] == y)
continue;
return a[id][i];
}
return -1;
}
bool dfs(int x, int now, int fa) {
if (x > n)
return 1;
if (x == n) {
ans[n] = find_oth(now, ans[n - 1], ans[1]);
if (ans[n] != -1)
return dfs(x + 1, get_nxt(fa, now), now);
}
ans[x] = find_oth(fa, ans[x - 1], ans[x - 2]);
if (in_(now, ans[x]) == 0)
return 0;
return dfs(x + 1, get_nxt(fa, now), now);
}
int cross(int x, int y, int z) {
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
if (a[x][i] == a[y][j])
for (int k = 0; k < 3; ++k)
if (a[x][i] == a[z][k])
return a[x][i];
return -1;
}
int main() {
mp.clear();
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
for (int j = 0; j < 3; ++j)
scanf("%d", &a[i][j]);
if (n == 3) {
puts("1 2 3");
return 0;
}
if (n == 4) {
puts("1 2 3 4");
return 0;
}
for (int i = 1; i <= n; ++i) {
addedge_solve(a[i][0], a[i][1], i);
addedge_solve(a[i][0], a[i][2], i);
addedge_solve(a[i][1], a[i][2], i);
}
/*
bool flag = 0;
for (int k = 0; k < 2; ++k) {
int nxt = G[1][k];
int sec = get_nxt(1, nxt);
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
if (flag == 0 && chk(a[1][i], a[nxt][j], nxt)) {
ans[1] = a[1][i];
ans[2] = a[nxt][j];
cerr << "? " << nxt << ' ' << sec << ' ' << ans[1] << ' ' << ans[2] << '\n';
flag = dfs(3, sec, nxt) &&
chk(ans[n], ans[2], 1) &&
chk(ans[1], ans[3], 2);
}
}
*/
//assert(flag == true);
int now = 1, nxt = G[1][0];
for (int i = 1; i <= n; ++i) {
int sec = get_nxt(now, nxt);
// cerr << ">> " << now << ' ' << nxt << '\n';
ans[i] = cross(now, nxt, sec);
now = nxt;
nxt = sec;
}
for (int i = 1; i <= n; ++i)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}