专题2024.03.21
2024.03.21专题
T1 Bombs
答案显然具有单调性,多删一定比少删更优,这是明显的
一个数 不被删掉的充要条件为:
其中 为 之前的炸弹数量
由单调性,考虑每次加一个炸弹后怎么快速的检查一个数合不合法,可以用线段树维护全局的 和区间加
时间复杂度为
code
// Author: xiaruize #ifndef ONLINE_JUDGE #define debug(x) cerr << "On Line:" << __LINE__ << #x << "=" << x << endl bool start_of_memory_use; #else #define debug(x) #endif #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE clock_t start_clock = clock(); #endif #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define mms(arr, n) memset(arr, n, sizeof(arr)) #define rep(i, a, n) for (int i = (a); i <= (n); ++i) #define per(i, n, a) for (int i = (n); i >= (a); --i) int max(int a, int b) { if (a > b) return a; return b; } int min(int a, int b) { if (a < b) return a; return b; } const int INF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1000000007; const int N = 3e5 + 10; struct segment_tree { #define ls p << 1 #define rs p << 1 | 1 struct node { int mx, lz; void tag(int x) { mx += x; lz += x; } } tr[N << 2]; void pushdown(int p) { tr[ls].tag(tr[p].lz); tr[rs].tag(tr[p].lz); tr[p].lz = 0; } void pushup(int p) { tr[p].mx = max(tr[ls].mx, tr[rs].mx); } void update(int p, int l, int r, int ll, int rr, int v) { if (ll <= l && r <= rr) { tr[p].tag(v); return; } pushdown(p); int mid = l + r >> 1; if (mid >= ll) update(ls, l, mid, ll, rr, v); if (mid < rr) update(rs, mid + 1, r, ll, rr, v); pushup(p); } } seg; int n; int p[N], q[N], pos[N]; void solve() { cin >> n; rep(i, 1, n) { cin >> p[i]; pos[p[i]] = i; } rep(i, 1, n) cin >> q[i]; seg.update(1, 1, n, 1, pos[n], 1); int res = n; cout << n << ' '; rep(i, 1, n - 1) { seg.update(1, 1, n, 1, q[i], -1); while (seg.tr[1].mx <= 0) { res--; seg.update(1, 1, n, 1, pos[res], 1); } cout << res << ' '; } } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; // cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
T2 P1484 种树
是 的,且不太好优化,故考虑贪心
假设当前选择了 ,且 周围2格都是空,那么下一步有两种情况
- 选择 并删除
- 选择不与 相邻的数
对于第一种情况的证明
考虑删除 后不选择
那么,选择 和新增的一个数必然覆盖的区间更小且价值更大
所以是不优的
所以如果删除 则必然选择
用链表和优先队列维护,每次选择一个,将两侧的删掉,当前的的权值改为 并重新压入优先队列
code
// Author: xiaruize #ifndef ONLINE_JUDGE #define debug(x) cerr << "On Line:" << __LINE__ << #x << "=" << x << endl bool start_of_memory_use; #else #define debug(x) #endif #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE clock_t start_clock = clock(); #endif #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define mms(arr, n) memset(arr, n, sizeof(arr)) #define rep(i, a, n) for (int i = (a); i <= (n); ++i) #define per(i, n, a) for (int i = (n); i >= (a); --i) int max(int a, int b) { if (a > b) return a; return b; } int min(int a, int b) { if (a < b) return a; return b; } const int INF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1000000007; const int N = 3e5 + 10; int n, k; int a[N << 1], pre[N], nxt[N]; priority_queue<pii> q; bool vis[N]; void del(int x) { nxt[pre[x]] = nxt[x]; pre[nxt[x]] = pre[x]; } void solve() { cin >> n >> k; rep(i, 1, n) { cin >> a[i]; pre[i] = i - 1; nxt[i] = i + 1; q.push({a[i], i}); } int res = 0; int ans = 0; while (k--) { while (vis[q.top().second]) q.pop(); int x = q.top().second; q.pop(); res += a[x]; ans = max(ans, res); a[x] = a[pre[x]] + a[nxt[x]] - a[x]; q.push({a[x], x}); vis[pre[x]] = vis[nxt[x]] = true; del(pre[x]); del(nxt[x]); } cout << ans << endl; } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; // cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
T3 Square Root of Permutation
从 建图
注意到一定形成若干个环,按照环长度的奇偶性分类
-
对于长度为奇数的环,令长度为 考虑如下答案 这里的 为点在环上的下标
-
对于长度为偶数的环,发现只可以通过等长的两两匹配
模拟即可
code
// Author: xiaruize #ifndef ONLINE_JUDGE bool start_of_memory_use; #else #define debug(x) #endif #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE clock_t start_clock = clock(); #endif namespace __DEBUG_UTIL__ { using namespace std; /* Primitive Datatypes Print */ void print(const char *x) { cerr << x; } void print(bool x) { cerr << (x ? "T" : "F"); } void print(char x) { cerr << '\'' << x << '\''; } void print(signed short int x) { cerr << x; } void print(unsigned short int x) { cerr << x; } void print(signed int x) { cerr << x; } void print(unsigned int x) { cerr << x; } void print(signed long int x) { cerr << x; } void print(unsigned long int x) { cerr << x; } void print(signed long long int x) { cerr << x; } void print(unsigned long long int x) { cerr << x; } void print(float x) { cerr << x; } void print(double x) { cerr << x; } void print(long double x) { cerr << x; } void print(string x) { cerr << '\"' << x << '\"'; } template <size_t N> void print(bitset<N> x) { cerr << x; } void print(vector<bool> v) { /* Overloaded this because stl optimizes vector<bool> by using _Bit_reference instead of bool to conserve space. */ int f = 0; cerr << '{'; for (auto &&i : v) cerr << (f++ ? "," : "") << (i ? "T" : "F"); cerr << "}"; } /* Templates Declarations to support nested datatypes */ template <typename T> void print(T &&x); template <typename T> void print(vector<vector<T>> mat); template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]); template <typename F, typename S> void print(pair<F, S> x); template <typename T, size_t N> struct Tuple; template <typename T> struct Tuple<T, 1>; template <typename... Args> void print(tuple<Args...> t); template <typename... T> void print(priority_queue<T...> pq); template <typename T> void print(stack<T> st); template <typename T> void print(queue<T> q); /* Template Datatypes Definitions */ template <typename T> void print(T &&x) { /* This works for every container that supports range-based loop i.e. vector, set, map, oset, omap, dequeue */ int f = 0; cerr << '{'; for (auto &&i : x) cerr << (f++ ? "," : ""), print(i); cerr << "}"; } template <typename T> void print(vector<vector<T>> mat) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename F, typename S> void print(pair<F, S> x) { cerr << '('; print(x.first); cerr << ','; print(x.second); cerr << ')'; } template <typename T, size_t N> struct Tuple { static void printTuple(T t) { Tuple<T, N - 1>::printTuple(t); cerr << ",", print(get<N - 1>(t)); } }; template <typename T> struct Tuple<T, 1> { static void printTuple(T t) { print(get<0>(t)); } }; template <typename... Args> void print(tuple<Args...> t) { cerr << "("; Tuple<decltype(t), sizeof...(Args)>::printTuple(t); cerr << ")"; } template <typename... T> void print(priority_queue<T...> pq) { int f = 0; cerr << '{'; while (!pq.empty()) cerr << (f++ ? "," : ""), print(pq.top()), pq.pop(); cerr << "}"; } template <typename T> void print(stack<T> st) { int f = 0; cerr << '{'; while (!st.empty()) cerr << (f++ ? "," : ""), print(st.top()), st.pop(); cerr << "}"; } template <typename T> void print(queue<T> q) { int f = 0; cerr << '{'; while (!q.empty()) cerr << (f++ ? "," : ""), print(q.front()), q.pop(); cerr << "}"; } /* Printer functions */ void printer(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printer(const char *names, T &&head, V &&...tail) { /* Using && to capture both lvalues and rvalues */ int i = 0; for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++) if (names[i] == '(' or names[i] == '<' or names[i] == '{') bracket++; else if (names[i] == ')' or names[i] == '>' or names[i] == '}') bracket--; cerr.write(names, i) << " = "; print(head); if (sizeof...(tail)) cerr << " ||", printer(names + i + 1, tail...); else cerr << "]\n"; } /* PrinterArr */ void printerArr(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printerArr(const char *names, T arr[], size_t N, V... tail) { size_t ind = 0; for (; names[ind] and names[ind] != ','; ind++) cerr << names[ind]; for (ind++; names[ind] and names[ind] != ','; ind++) ; cerr << " = {"; for (size_t i = 0; i < N; i++) cerr << (i ? "," : ""), print(arr[i]); cerr << "}"; if (sizeof...(tail)) cerr << " ||", printerArr(names + ind + 1, tail...); else cerr << "]\n"; } } #ifndef ONLINE_JUDGE #define debug(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__) #define debugArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__) #else #define debug(...) #define debugArr(...) #endif #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define mms(arr, n) memset(arr, n, sizeof(arr)) #define rep(i, a, n) for (int i = (a); i <= (n); ++i) #define per(i, n, a) for (int i = (n); i >= (a); --i) int max(int a, int b) { if (a > b) return a; return b; } int min(int a, int b) { if (a < b) return a; return b; } const int INF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1000000007; const int N = 1e6 + 10; int n; int p[N]; bool vis[N]; int res[N]; vector<int> vec; map<int, vector<vector<int>>> siz; void solve() { cin >> n; rep(i, 1, n) cin >> p[i]; rep(i, 1, n) { if (!vis[i]) { vec.clear(); vec.push_back(i); vis[i] = true; int x = p[i]; while (x != i) { vec.push_back(x); vis[x] = true; x = p[x]; } debug(vec.size()); if (vec.size() & 1) { int len = vec.size(); rep(i, 0, len / 2 - 1) { res[vec[i]] = vec[len / 2 + i + 1]; res[vec[len / 2 + i + 1]] = vec[i + 1]; } res[vec[len / 2]] = vec[0]; } else { siz[vec.size()].push_back(vec); } } } for (auto [len, cur] : siz) { if (cur.size() % 2 == 1) { cout << "-1" << endl; return; } for (int i = 0; i < cur.size(); i += 2) { rep(j, 0, len - 1) { res[cur[i][j]] = cur[i + 1][j]; res[cur[i + 1][j]] = (j == len - 1 ? cur[i][0] : cur[i][j + 1]); } } } rep(i, 1, n) cout << res[i] << ' '; } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; // cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
T5 P3825 [NOI2017] 游戏
如果不存在 的点,即每个点都只有 种可能,那么就可以转化为相互限制的条件,就是 2-SAT
板子了
枚举每个当前是 的位置改为 还是 ,做上面的算法即可
为什么不用枚举 的情况,在考虑 的时候,已经考虑了当前这位在答案中为所有字母的情况,所以就不需要再考虑 了
code
// Author: xiaruize #ifndef ONLINE_JUDGE bool start_of_memory_use; #else #define debug(x) #endif #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE clock_t start_clock = clock(); #endif namespace __DEBUG_UTIL__ { using namespace std; /* Primitive Datatypes Print */ void print(const char *x) { cerr << x; } void print(bool x) { cerr << (x ? "T" : "F"); } void print(char x) { cerr << '\'' << x << '\''; } void print(signed short int x) { cerr << x; } void print(unsigned short int x) { cerr << x; } void print(signed int x) { cerr << x; } void print(unsigned int x) { cerr << x; } void print(signed long int x) { cerr << x; } void print(unsigned long int x) { cerr << x; } void print(signed long long int x) { cerr << x; } void print(unsigned long long int x) { cerr << x; } void print(float x) { cerr << x; } void print(double x) { cerr << x; } void print(long double x) { cerr << x; } void print(string x) { cerr << '\"' << x << '\"'; } template <size_t N> void print(bitset<N> x) { cerr << x; } void print(vector<bool> v) { /* Overloaded this because stl optimizes vector<bool> by using _Bit_reference instead of bool to conserve space. */ int f = 0; cerr << '{'; for (auto &&i : v) cerr << (f++ ? "," : "") << (i ? "T" : "F"); cerr << "}"; } /* Templates Declarations to support nested datatypes */ template <typename T> void print(T &&x); template <typename T> void print(vector<vector<T>> mat); template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]); template <typename F, typename S> void print(pair<F, S> x); template <typename T, size_t N> struct Tuple; template <typename T> struct Tuple<T, 1>; template <typename... Args> void print(tuple<Args...> t); template <typename... T> void print(priority_queue<T...> pq); template <typename T> void print(stack<T> st); template <typename T> void print(queue<T> q); /* Template Datatypes Definitions */ template <typename T> void print(T &&x) { /* This works for every container that supports range-based loop i.e. vector, set, map, oset, omap, dequeue */ int f = 0; cerr << '{'; for (auto &&i : x) cerr << (f++ ? "," : ""), print(i); cerr << "}"; } template <typename T> void print(vector<vector<T>> mat) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename F, typename S> void print(pair<F, S> x) { cerr << '('; print(x.first); cerr << ','; print(x.second); cerr << ')'; } template <typename T, size_t N> struct Tuple { static void printTuple(T t) { Tuple<T, N - 1>::printTuple(t); cerr << ",", print(get<N - 1>(t)); } }; template <typename T> struct Tuple<T, 1> { static void printTuple(T t) { print(get<0>(t)); } }; template <typename... Args> void print(tuple<Args...> t) { cerr << "("; Tuple<decltype(t), sizeof...(Args)>::printTuple(t); cerr << ")"; } template <typename... T> void print(priority_queue<T...> pq) { int f = 0; cerr << '{'; while (!pq.empty()) cerr << (f++ ? "," : ""), print(pq.top()), pq.pop(); cerr << "}"; } template <typename T> void print(stack<T> st) { int f = 0; cerr << '{'; while (!st.empty()) cerr << (f++ ? "," : ""), print(st.top()), st.pop(); cerr << "}"; } template <typename T> void print(queue<T> q) { int f = 0; cerr << '{'; while (!q.empty()) cerr << (f++ ? "," : ""), print(q.front()), q.pop(); cerr << "}"; } /* Printer functions */ void printer(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printer(const char *names, T &&head, V &&...tail) { /* Using && to capture both lvalues and rvalues */ int i = 0; for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++) if (names[i] == '(' or names[i] == '<' or names[i] == '{') bracket++; else if (names[i] == ')' or names[i] == '>' or names[i] == '}') bracket--; cerr.write(names, i) << " = "; print(head); if (sizeof...(tail)) cerr << " ||", printer(names + i + 1, tail...); else cerr << "]\n"; } /* PrinterArr */ void printerArr(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printerArr(const char *names, T arr[], size_t N, V... tail) { size_t ind = 0; for (; names[ind] and names[ind] != ','; ind++) cerr << names[ind]; for (ind++; names[ind] and names[ind] != ','; ind++) ; cerr << " = {"; for (size_t i = 0; i < N; i++) cerr << (i ? "," : ""), print(arr[i]); cerr << "}"; if (sizeof...(tail)) cerr << " ||", printerArr(names + ind + 1, tail...); else cerr << "]\n"; } } #ifndef ONLINE_JUDGE #define debug(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__) #define debugArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__) #else #define debug(...) #define debugArr(...) #endif // #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define mms(arr, n) memset(arr, n, sizeof(arr)) #define rep(i, a, n) for (int i = (a); i <= (n); ++i) #define per(i, n, a) for (int i = (n); i >= (a); --i) int max(int a, int b) { if (a > b) return a; return b; } int min(int a, int b) { if (a < b) return a; return b; } const int INF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1000000007; const int N = 1e5 + 10; struct lim { int x, y; char a, b; } lim[N]; int n, m, d; char s[N]; vector<int> pos; char c1[N], c2[N]; namespace twosat { #define maxn 1000010 struct edge { int to, nxt; } e[maxn]; int head[maxn], edge_cnt; void add(int from, int to) { e[++edge_cnt] = (edge){to, head[from]}; head[from] = edge_cnt; } int dfn_cnt, co_cnt, top; int dfn[maxn], low[maxn], co[maxn], st[maxn]; bool vis[maxn]; void tarjan(int x) { dfn[x] = low[x] = ++dfn_cnt; st[++top] = x; vis[x] = true; for (int i = head[x]; i; i = e[i].nxt) { int y = e[i].to; if (!dfn[y]) { tarjan(y); ; low[x] = min(low[x], low[y]); } else if (vis[y]) low[x] = min(low[x], dfn[y]); } if (low[x] == dfn[x]) { co_cnt++; int now; do { now = st[top--]; vis[now] = false; co[now] = co_cnt; } while (now != x); } } bool check() { for (int i = 1; i <= 2 * n; ++i) if (!dfn[i]) tarjan(i); for (int i = 1; i <= n; ++i) if (co[i] == co[i + n]) return false; return true; } void init() { edge_cnt = dfn_cnt = co_cnt = top = 0; memset(st, 0, sizeof(st)); memset(co, 0, sizeof(co)); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(vis, 0, sizeof(vis)); memset(head, 0, sizeof(head)); } } void solve() { cin >> n >> d; cin >> (s + 1); rep(i, 1, n) { if (s[i] == 'x') pos.push_back(i); if (s[i] == 'a') { c1[i] = 'b'; c2[i] = 'c'; } if (s[i] == 'b') { c1[i] = 'a'; c2[i] = 'c'; } if (s[i] == 'c') { c1[i] = 'a'; c2[i] = 'b'; } } cin >> m; rep(i, 1, m) { cin >> lim[i].x >> lim[i].a >> lim[i].y >> lim[i].b; lim[i].a -= 'A' - 'a'; lim[i].b -= 'A' - 'a'; } rep(msk, 0, (1 << d) - 1) { rep(i, 0, d - 1) { if (msk & (1 << i)) { s[pos[i]] = 'a'; c1[pos[i]] = 'b'; c2[pos[i]] = 'c'; } else { s[pos[i]] = 'b'; c1[pos[i]] = 'a'; c2[pos[i]] = 'c'; } } twosat::init(); rep(i, 1, m) { if (s[lim[i].x] == lim[i].a) continue; if (s[lim[i].y] == lim[i].b) twosat::add(lim[i].x + (c2[lim[i].x] == lim[i].a) * n, lim[i].x + (c1[lim[i].x] == lim[i].a) * n); else { twosat::add(lim[i].x + (c2[lim[i].x] == lim[i].a) * n, lim[i].y + (c2[lim[i].y] == lim[i].b) * n); twosat::add(lim[i].y + (c1[lim[i].y] == lim[i].b) * n, lim[i].x + (c1[lim[i].x] == lim[i].a) * n); } } if (twosat::check()) { rep(i, 1, n) { if (twosat::co[i] > twosat::co[i + n]) cout << (char)(c2[i] - 'a' + 'A'); else cout << (char)(c1[i] - 'a' + 'A'); } return; } } cout << "-1" << endl; } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; // cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
J P4006 小 Y 和二叉树
贪心的选择最小的 的点作为遍历序列的第一个点
然后分两种
- 下一个点为当前点的右子树
- 下一个点为当前点的祖先节点
考虑分类讨论这个东西
因为一开始的点是确定的,那么由一个点出发的子树的序列的第一个数可以 求
如果 ,将当前点出发,连向的 值较小的挂到右子树,否则挂为父亲
否则根据 分类
code
// Author: xiaruize #ifndef ONLINE_JUDGE bool start_of_memory_use; #else #define debug(x) #endif #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE clock_t start_clock = clock(); #endif namespace __DEBUG_UTIL__ { using namespace std; /* Primitive Datatypes Print */ void print(const char *x) { cerr << x; } void print(bool x) { cerr << (x ? "T" : "F"); } void print(char x) { cerr << '\'' << x << '\''; } void print(signed short int x) { cerr << x; } void print(unsigned short int x) { cerr << x; } void print(signed int x) { cerr << x; } void print(unsigned int x) { cerr << x; } void print(signed long int x) { cerr << x; } void print(unsigned long int x) { cerr << x; } void print(signed long long int x) { cerr << x; } void print(unsigned long long int x) { cerr << x; } void print(float x) { cerr << x; } void print(double x) { cerr << x; } void print(long double x) { cerr << x; } void print(string x) { cerr << '\"' << x << '\"'; } template <size_t N> void print(bitset<N> x) { cerr << x; } void print(vector<bool> v) { /* Overloaded this because stl optimizes vector<bool> by using _Bit_reference instead of bool to conserve space. */ int f = 0; cerr << '{'; for (auto &&i : v) cerr << (f++ ? "," : "") << (i ? "T" : "F"); cerr << "}"; } /* Templates Declarations to support nested datatypes */ template <typename T> void print(T &&x); template <typename T> void print(vector<vector<T>> mat); template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]); template <typename F, typename S> void print(pair<F, S> x); template <typename T, size_t N> struct Tuple; template <typename T> struct Tuple<T, 1>; template <typename... Args> void print(tuple<Args...> t); template <typename... T> void print(priority_queue<T...> pq); template <typename T> void print(stack<T> st); template <typename T> void print(queue<T> q); /* Template Datatypes Definitions */ template <typename T> void print(T &&x) { /* This works for every container that supports range-based loop i.e. vector, set, map, oset, omap, dequeue */ int f = 0; cerr << '{'; for (auto &&i : x) cerr << (f++ ? "," : ""), print(i); cerr << "}"; } template <typename T> void print(vector<vector<T>> mat) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename F, typename S> void print(pair<F, S> x) { cerr << '('; print(x.first); cerr << ','; print(x.second); cerr << ')'; } template <typename T, size_t N> struct Tuple { static void printTuple(T t) { Tuple<T, N - 1>::printTuple(t); cerr << ",", print(get<N - 1>(t)); } }; template <typename T> struct Tuple<T, 1> { static void printTuple(T t) { print(get<0>(t)); } }; template <typename... Args> void print(tuple<Args...> t) { cerr << "("; Tuple<decltype(t), sizeof...(Args)>::printTuple(t); cerr << ")"; } template <typename... T> void print(priority_queue<T...> pq) { int f = 0; cerr << '{'; while (!pq.empty()) cerr << (f++ ? "," : ""), print(pq.top()), pq.pop(); cerr << "}"; } template <typename T> void print(stack<T> st) { int f = 0; cerr << '{'; while (!st.empty()) cerr << (f++ ? "," : ""), print(st.top()), st.pop(); cerr << "}"; } template <typename T> void print(queue<T> q) { int f = 0; cerr << '{'; while (!q.empty()) cerr << (f++ ? "," : ""), print(q.front()), q.pop(); cerr << "}"; } /* Printer functions */ void printer(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printer(const char *names, T &&head, V &&...tail) { /* Using && to capture both lvalues and rvalues */ int i = 0; for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++) if (names[i] == '(' or names[i] == '<' or names[i] == '{') bracket++; else if (names[i] == ')' or names[i] == '>' or names[i] == '}') bracket--; cerr.write(names, i) << " = "; print(head); if (sizeof...(tail)) cerr << " ||", printer(names + i + 1, tail...); else cerr << "]\n"; } /* PrinterArr */ void printerArr(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printerArr(const char *names, T arr[], size_t N, V... tail) { size_t ind = 0; for (; names[ind] and names[ind] != ','; ind++) cerr << names[ind]; for (ind++; names[ind] and names[ind] != ','; ind++) ; cerr << " = {"; for (size_t i = 0; i < N; i++) cerr << (i ? "," : ""), print(arr[i]); cerr << "}"; if (sizeof...(tail)) cerr << " ||", printerArr(names + ind + 1, tail...); else cerr << "]\n"; } } #ifndef ONLINE_JUDGE #define debug(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__) #define debugArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__) #else #define debug(...) #define debugArr(...) #endif #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define mms(arr, n) memset(arr, n, sizeof(arr)) #define rep(i, a, n) for (int i = (a); i <= (n); ++i) #define per(i, n, a) for (int i = (n); i >= (a); --i) int max(int a, int b) { if (a > b) return a; return b; } int min(int a, int b) { if (a < b) return a; return b; } const int INF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1000000007; const int N = 1e6 + 10; int n; vector<int> g[N]; int rt = -1; int dp[N]; void dfs(int x, int fa) { if (g[x].size() <= 2) dp[x] = x; for (auto v : g[x]) { if (v == fa) continue; dfs(v, x); dp[x] = min(dp[x], dp[v]); } } void calc(int x, int fa, bool flag) { if (flag) { bool fl = false; if (g[x].size() < 3) { for (auto v : g[x]) { if (v == fa) continue; if (dp[v] > x) { cout << x << ' '; fl = true; } calc(v, x, flag); } } else { bool fr = true; for (auto v : g[x]) { if (v == fa) continue; calc(v, x, flag); if (fr) { cout << x << ' '; fr = false; fl = true; } } } if (!fl) cout << x << ' '; return; } cout << x << ' '; if (g[x].size() == 2) { for (auto v : g[x]) if (v != fa) calc(v, x, dp[v] < v); } else if (g[x].size() == 3) { bool fr = true; for (auto v : g[x]) { if (v != fa) { calc(v, x, fr); fr = false; } } } } bool cmp(int x, int y) { return dp[x] < dp[y]; } void solve() { cin >> n; rep(i, 1, n) { int x; cin >> x; rep(j, 1, x) { int v; cin >> v; g[i].push_back(v); } if (g[i].size() <= 2 && rt == -1) rt = i; } memset(dp, 0x3f, sizeof(dp)); g[rt].push_back(rt); dfs(rt, 0); rep(i, 1, n) sort(ALL(g[i]), cmp); calc(rt, rt, 0); } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen("binary.in", "r", stdin); // freopen("binary.out", "w", stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; // cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
P7515 [省选联考 2021 A 卷] 矩阵游戏
先忽略上下界的条件,构造一个可行的方案,考虑怎么调整
发现可以进行这样的操作
使得最后的数组合法
这样其实相当于每个格子都给出了一个不等式,然后差分约束即可
code
// Author: xiaruize #ifndef ONLINE_JUDGE bool start_of_memory_use; #else #define debug(x) #endif #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE clock_t start_clock = clock(); #endif namespace __DEBUG_UTIL__ { using namespace std; /* Primitive Datatypes Print */ void print(const char *x) { cerr << x; } void print(bool x) { cerr << (x ? "T" : "F"); } void print(char x) { cerr << '\'' << x << '\''; } void print(signed short int x) { cerr << x; } void print(unsigned short int x) { cerr << x; } void print(signed int x) { cerr << x; } void print(unsigned int x) { cerr << x; } void print(signed long int x) { cerr << x; } void print(unsigned long int x) { cerr << x; } void print(signed long long int x) { cerr << x; } void print(unsigned long long int x) { cerr << x; } void print(float x) { cerr << x; } void print(double x) { cerr << x; } void print(long double x) { cerr << x; } void print(string x) { cerr << '\"' << x << '\"'; } template <size_t N> void print(bitset<N> x) { cerr << x; } void print(vector<bool> v) { /* Overloaded this because stl optimizes vector<bool> by using _Bit_reference instead of bool to conserve space. */ int f = 0; cerr << '{'; for (auto &&i : v) cerr << (f++ ? "," : "") << (i ? "T" : "F"); cerr << "}"; } /* Templates Declarations to support nested datatypes */ template <typename T> void print(T &&x); template <typename T> void print(vector<vector<T>> mat); template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]); template <typename F, typename S> void print(pair<F, S> x); template <typename T, size_t N> struct Tuple; template <typename T> struct Tuple<T, 1>; template <typename... Args> void print(tuple<Args...> t); template <typename... T> void print(priority_queue<T...> pq); template <typename T> void print(stack<T> st); template <typename T> void print(queue<T> q); /* Template Datatypes Definitions */ template <typename T> void print(T &&x) { /* This works for every container that supports range-based loop i.e. vector, set, map, oset, omap, dequeue */ int f = 0; cerr << '{'; for (auto &&i : x) cerr << (f++ ? "," : ""), print(i); cerr << "}"; } template <typename T> void print(vector<vector<T>> mat) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename T, size_t N, size_t M> void print(T (&mat)[N][M]) { int f = 0; cerr << "\n~~~~~\n"; for (auto &&i : mat) { cerr << setw(2) << left << f++, print(i), cerr << "\n"; } cerr << "~~~~~\n"; } template <typename F, typename S> void print(pair<F, S> x) { cerr << '('; print(x.first); cerr << ','; print(x.second); cerr << ')'; } template <typename T, size_t N> struct Tuple { static void printTuple(T t) { Tuple<T, N - 1>::printTuple(t); cerr << ",", print(get<N - 1>(t)); } }; template <typename T> struct Tuple<T, 1> { static void printTuple(T t) { print(get<0>(t)); } }; template <typename... Args> void print(tuple<Args...> t) { cerr << "("; Tuple<decltype(t), sizeof...(Args)>::printTuple(t); cerr << ")"; } template <typename... T> void print(priority_queue<T...> pq) { int f = 0; cerr << '{'; while (!pq.empty()) cerr << (f++ ? "," : ""), print(pq.top()), pq.pop(); cerr << "}"; } template <typename T> void print(stack<T> st) { int f = 0; cerr << '{'; while (!st.empty()) cerr << (f++ ? "," : ""), print(st.top()), st.pop(); cerr << "}"; } template <typename T> void print(queue<T> q) { int f = 0; cerr << '{'; while (!q.empty()) cerr << (f++ ? "," : ""), print(q.front()), q.pop(); cerr << "}"; } /* Printer functions */ void printer(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printer(const char *names, T &&head, V &&...tail) { /* Using && to capture both lvalues and rvalues */ int i = 0; for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++) if (names[i] == '(' or names[i] == '<' or names[i] == '{') bracket++; else if (names[i] == ')' or names[i] == '>' or names[i] == '}') bracket--; cerr.write(names, i) << " = "; print(head); if (sizeof...(tail)) cerr << " ||", printer(names + i + 1, tail...); else cerr << "]\n"; } /* PrinterArr */ void printerArr(const char *) {} /* Base Recursive */ template <typename T, typename... V> void printerArr(const char *names, T arr[], size_t N, V... tail) { size_t ind = 0; for (; names[ind] and names[ind] != ','; ind++) cerr << names[ind]; for (ind++; names[ind] and names[ind] != ','; ind++) ; cerr << " = {"; for (size_t i = 0; i < N; i++) cerr << (i ? "," : ""), print(arr[i]); cerr << "}"; if (sizeof...(tail)) cerr << " ||", printerArr(names + ind + 1, tail...); else cerr << "]\n"; } } #ifndef ONLINE_JUDGE #define debug(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__) #define debugArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__) #else #define debug(...) #define debugArr(...) #endif #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define mms(arr, n) memset(arr, n, sizeof(arr)) #define rep(i, a, n) for (int i = (a); i <= (n); ++i) #define per(i, n, a) for (int i = (n); i >= (a); --i) int max(int a, int b) { if (a > b) return a; return b; } int min(int a, int b) { if (a < b) return a; return b; } const int INF = 0x3f3f3f3f3f3f3f3f; const int MOD = 1000000007; const int N = 6e2 + 10; int n, m; int a[N][N], b[N][N]; vector<pii> g[N]; int dis[N]; bool vis[N]; int cnt[N]; void solve() { cin >> n >> m; rep(i, 0, n + m) g[i].clear(); mms(a, 0); rep(i, 1, n) { rep(j, 1, m) { if (i < n && j < m) cin >> b[i][j]; if (i != 1 && j != 1) a[i][j] = b[i - 1][j - 1] - a[i - 1][j - 1] - a[i - 1][j] - a[i][j - 1]; } } // debug(a); rep(i, 1, n) { rep(j, 1, m) { if ((i + j) & 1) { g[i].push_back({j + n, a[i][j]}); g[j + n].push_back({i, 1e6 - a[i][j]}); } else { g[i].push_back({j + n, 1e6 - a[i][j]}); g[j + n].push_back({i, a[i][j]}); } } } rep(i, 1, n + m) { g[0].push_back({i, 0}); } queue<int> q; memset(dis, 0x3f, sizeof(dis)); mms(vis, 0); q.push(0); dis[0] = 0; vis[0] = true; while (!q.empty()) { int x = q.front(); q.pop(); vis[x] = false; for (auto [v, w] : g[x]) { if (dis[v] > dis[x] + w) { dis[v] = dis[x] + w; cnt[v] = cnt[x] + 1; if (cnt[v] > n + m) { NO; return; } if (!vis[v]) { q.push(v); vis[v] = true; } } } } YES; rep(i, 1, n) { rep(j, 1, m) { if ((i + j) & 1) cout << a[i][j] + dis[i] - dis[j + n] << ' '; else cout << a[i][j] - dis[i] + dis[j + n] << ' '; } cout << endl; } } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
本文作者:xiaruize's Blog
本文链接:https://www.cnblogs.com/xiaruize/p/18086242
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步