2024.03 模擬賽記錄
2024.03.20
TheBrickTowerMediumDivOne
不考慮相同元素順序,最優解的形式為,將原序列從小到大排序,從前往後依次放在當前答案的開頭或者結尾
考慮相同元素的影響,發現在貪心的同時記錄當前放在首尾的同樣元素的編號
然後貪心的把小的編號靠前即可
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 = 47 + 10;
int n;
pii a[N];
vector<pii> vec[N];
deque<int> res;
void solve()
{
cin >> n;
rep(i, 1, n)
{
cin >> a[i].first;
a[i].second = i - 1;
vec[a[i].first].push_back(a[i]);
}
rep(i, 1, 50)
{
if (res.empty() && vec[i].size())
{
sort(ALL(vec[i]));
for (auto v : vec[i])
res.push_back(v.second);
continue;
}
vector<int> ls, rs;
for (auto v : vec[i])
{
if (v.second < res.front())
ls.push_back(v.second);
else
rs.push_back(v.second);
}
sort(ALL(ls));
reverse(ALL(ls));
for (auto v : ls)
res.push_front(v);
sort(ALL(rs));
for (auto v : rs)
res.push_back(v);
}
for (auto v : res)
cout << v << ' ';
}
#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;
}
Incubator
很好的二分圖匹配題
原問題等價於將原來的圖中能相互到達的邊全部相連,然後求最大獨立集
然後對每個點拆點,按照連通性建圖,然後得到一個二分圖,dinic或者匈牙利都可以
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 = 2e5 + 10;
struct MF
{
struct edge
{
int v, nxt, cap, flow;
} e[N];
int fir[N], cnt = 0;
int n, S, T;
int maxflow = 0;
int dep[N], cur[N];
void init()
{
// cerr << "flag" << endl;
memset(fir, -1, sizeof(fir));
cnt = 0;
}
void addedge(int u, int v, int w)
{
e[cnt] = {v, fir[u], w, 0};
fir[u] = cnt++;
e[cnt] = {u, fir[v], 0, 0};
fir[v] = cnt++;
}
bool bfs()
{
queue<int> q;
memset(dep, 0, sizeof(int) * (n + 1));
dep[S] = 1;
q.push(S);
while (q.size())
{
int u = q.front();
q.pop();
for (int i = fir[u]; ~i; i = e[i].nxt)
{
int v = e[i].v;
if ((!dep[v]) && (e[i].cap > e[i].flow))
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[T];
}
int dfs(int u, int flow)
{
if ((u == T) || (!flow))
return flow;
int ret = 0;
for (int &i = cur[u]; ~i; i = e[i].nxt)
{
int v = e[i].v, d;
if ((dep[v] == dep[u] + 1) && (d = dfs(v, min(flow - ret, e[i].cap - e[i].flow))))
{
ret += d;
e[i].flow += d;
e[i ^ 1].flow -= d;
if (ret == flow)
return ret;
}
}
return ret;
}
void dinic()
{
while (bfs())
{
memcpy(cur, fir, sizeof(int) * (n + 1));
maxflow += dfs(S, INF);
// cerr << maxflow << endl;
}
}
} mf;
const int M = 50 + 10;
int n;
char s[M][M];
bool dis[M][M];
void solve()
{
cin >> n;
rep(i, 1, n) cin >> (s[i] + 1);
rep(i, 1, n)
{
rep(j, 1, n)
{
dis[i][j] = (s[i][j] == 'Y' ? 1 : 0);
}
}
rep(k, 1, n)
{
rep(i, 1, n)
{
rep(j, 1, n)
{
dis[i][j] |= (dis[i][k] & dis[k][j]);
}
}
}
mf.init();
rep(i, 1, n)
{
mf.addedge(0, i, 1);
mf.addedge(i + n, n + n + 1, 1);
rep(j, 1, n)
{
if (dis[i][j])
{
debug(i, j);
mf.addedge(i, j + n, 1);
}
}
}
mf.n = mf.T = n + n + 1;
mf.dinic();
cout << n - mf.maxflow << 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;
}
TwoConvexShapes
其實並不是很難的題
觀察性質,發現可以透過旋轉,使得左上角為 B
, 右下角為 W
, 這樣的方案數顯然可以 dp[i][j]
表示第 \(i\) 行 \(j\) 列為 B
發現這樣會重複,具體分為 \(3\) 種情況
- 左側一個矩形為
B
,右側一個矩形為W
- 上面一個矩形為
B
,下面一個矩形為W
- 全部為
B
都很好計算,簡單容斥一下即可
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 = 50 + 10;
int n, m;
char s[N][N];
int dp[N][N];
bool fl[N][N];
void pre()
{
memset(fl, 0, sizeof(fl));
rep(i, 1, n)
{
rep(j, 0, m)
{
fl[i][j] = true;
rep(k, 1, j) fl[i][j] &= (s[i][k] != 'W');
rep(k, j + 1, m) fl[i][j] &= (s[i][k] != 'B');
}
}
}
int calc()
{
// debug(s);
// rep(i, 1, n)
// {
// rep(j, 1, m) cerr << s[i][j] << ' ';
// cerr << endl;
// }
// pre();
int res = 0;
memset(dp, 0, sizeof(dp));
rep(i, 0, m) dp[0][i] = 1;
rep(i, 1, n)
{
rep(j, 0, m)
{
if (j)
dp[i][j] = dp[i][j - 1];
else
dp[i][j] = 0;
(dp[i][j] += dp[i - 1][j] * fl[i][j] % MOD) %= MOD;
}
}
debug(dp[n][m]);
return dp[n][m];
}
int res = 0;
void slv()
{
pre();
rep(i, 0, n)
{
bool flag = true;
rep(j, 1, i) flag &= (fl[j][m]);
rep(j, i + 1, n) flag &= (fl[j][0]);
res -= flag;
}
rep(i, 0, m)
{
bool flag = true;
rep(j, 1, n) flag &= (fl[j][i]);
res -= flag;
}
bool flag = true;
rep(i, 1, n) rep(j, 1, m) flag &= (s[i][j] != 'W');
res += flag;
res += calc();
debug(res);
rep(i, 1, n / 2)
{
rep(j, 0, m)
{
// swap(s[i][j], s[n - i + 1][j]);
swap(fl[i][j], fl[n - i + 1][j]);
}
// reverse(s[i] + 1, s[i] + m + 1);
// reverse(fl[i] + 1, fl[i] + m + 1);
}
res += calc();
debug(res);
}
void solve()
{
cin >> n;
rep(i, 1, n) cin >> (s[i] + 1);
m = strlen(s[1] + 1);
slv();
rep(i, 1, n) rep(j, 1, m) if (s[i][j] != '?') s[i][j] = (s[i][j] == 'B' ? 'W' : 'B');
slv();
cout << (res % MOD + MOD) % MOD << 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;
}
ConversionMachine
\(dp_{i,j}\) 表示有 \(i\) 個位置已經合法,\(j\) 個位置差一步合法的方案數
轉移考慮改變的位置即可,注意到,要使得最後答案合法,步數的最大值和同步數下的代價是一樣的,可以直接計算,而每一步轉移又是一樣的
結合 \(10^9\) 的資料範圍,容易想到矩陣最佳化,矩陣不超過 \(100\times 100\) 可以透過
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 = 11 + 10;
int s[N], t[N];
int a[3];
int n;
int cnt = 0, ct = 0;
int sum = 0;
int maxcost;
void solve()
{
string str;
cin >> str;
rep(i, 0, str.size() - 1) s[i + 1] = str[i] - '0';
cin >> str;
rep(i, 0, str.size() - 1) t[i + 1] = str[i] - '0';
cin >> n;
n = str.size();
rep(i, 0, 2)
{
cin >> a[i];
sum += a[i];
}
cin >> maxcost;
rep(i, 1, n)
{
int tmp = 0;
while (s[i] != t[i])
{
tmp++;
cnt += a[s[i]];
s[i]++;
s[i] %= 3;
}
ct += tmp;
}
}
#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;
}
CosmicBlocks
一堆普及組和板子套在一起()
- 暴力列舉每個顏色的高度
- 暴力列舉兩個高度相鄰的顏色是否接觸
- 有源匯上下界網路流判斷是否存在合法的堆疊
- next_permutation計算合法方案數
其中 1,2,4
是普及知識點,3
是板子
堆在一起就不會了/kk
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 = 30;
struct MF
{
struct edge
{
int v, nxt, cap, flow;
} e[105];
int fir[105], cnt = 0;
int n, S, T;
int maxflow = 0;
int dep[105], cur[105];
void init()
{
// cerr << "flag" << endl;
memset(fir, -1, sizeof(fir));
memset(e, 0, sizeof(e));
cnt = 0;
maxflow = 0;
n = S = T = 0;
}
void addedge(int u, int v, int w)
{
e[cnt] = {v, fir[u], w, 0};
fir[u] = cnt++;
e[cnt] = {u, fir[v], 0, 0};
fir[v] = cnt++;
}
bool bfs()
{
queue<int> q;
memset(dep, 0, sizeof(int) * (n + 1));
dep[S] = 1;
q.push(S);
while (q.size())
{
int u = q.front();
q.pop();
for (int i = fir[u]; ~i; i = e[i].nxt)
{
int v = e[i].v;
if ((!dep[v]) && (e[i].cap > e[i].flow))
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[T];
}
int dfs(int u, int flow)
{
if ((u == T) || (!flow))
return flow;
int ret = 0;
for (int &i = cur[u]; ~i; i = e[i].nxt)
{
int v = e[i].v, d;
if ((dep[v] == dep[u] + 1) && (d = dfs(v, min(flow - ret, e[i].cap - e[i].flow))))
{
ret += d;
e[i].flow += d;
e[i ^ 1].flow -= d;
if (ret == flow)
return ret;
}
}
return ret;
}
void dinic()
{
while (bfs())
{
memcpy(cur, fir, sizeof(int) * (n + 1));
maxflow += dfs(S, INF);
// cerr << maxflow << endl;
}
}
} mf;
int n;
int a[N], mi, mx;
int lv[N];
bool g[N][N];
int p[N];
int deg[N];
vector<pii> vec;
bool check()
{
// debug(lv);
mf.init();
memset(deg, 0, sizeof(deg));
rep(i, 1, n)
{
// mf.addedge(i, i + n, 0);
deg[i] -= a[i];
deg[i + n] += a[i];
mf.addedge(n * 2 + 1, i, INF);
if (lv[i] == 1)
{
mf.addedge(i + n, n * 2 + 2, INF);
}
}
rep(i, 1, n)
{
rep(j, 1, n) if (g[i][j])
{
// debug(i, j);
mf.addedge(i + n, j, INF);
deg[i + n]--;
deg[j]++;
}
}
int sum = 0;
rep(i, 1, n * 2 + 2)
{
if (deg[i] > 0)
{
mf.addedge(n * 2 + 3, i, deg[i]);
sum += deg[i];
}
if (deg[i] < 0)
mf.addedge(i, n * 2 + 4, -deg[i]);
}
mf.addedge(n * 2 + 2, n * 2 + 1, INF);
mf.S = n * 2 + 3;
mf.n = mf.T = n * 2 + 4;
mf.dinic();
// debug(mf.maxflow, sum);
return mf.maxflow == sum;
}
void solve()
{
cin >> n;
rep(i, 1, n)
{
cin >> a[i];
lv[i] = 1;
}
cin >> mi >> mx;
int res = 0;
while (!lv[n + 1])
{
vec.clear();
vector<int> uni;
rep(i, 1, n)
{
uni.push_back(lv[i]);
rep(j, 1, n)
{
if (lv[i] + 1 == lv[j])
{
vec.push_back({j, i});
}
}
}
sort(ALL(uni));
uni.resize(unique(ALL(uni)) - uni.begin());
bool flg = true;
rep(i, 0, uni.size() - 1) if (uni[i] != i + 1)
{
flg = false;
break;
}
if (flg)
{
// debug(lv);
// debug(vec);
int tmp = vec.size();
// debug(tmp);
rep(msk, 0, (1 << tmp) - 1)
{
memset(g, 0, sizeof(g));
rep(i, 0, tmp - 1)
{
// debug(i);
if (msk & (1 << i))
{
g[vec[i].first][vec[i].second] = true;
}
}
if (check())
{
// debug(lv);
// debug(g);
int cnt = 0;
rep(i, 1, n) p[i] = i;
do
{
bool flag = true;
rep(i, 1, n)
{
rep(j, i + 1, n)
{
if (g[p[j]][p[i]])
{
flag = false;
break;
}
}
if (!flag)
break;
}
cnt += flag;
} while (next_permutation(p + 1, p + n + 1));
// debug(cnt);
if (mi <= cnt && cnt <= mx)
{
res++;
}
}
}
}
lv[1]++;
int x = 1;
while (x <= n && lv[x] == n + 1)
{
lv[x] = 1;
lv[x + 1]++;
x++;
}
// debug(lv);
}
cout << res << 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;
}
2024.03.22
字串
觀察到如下性質,當兩次出現的初始位置間隔為 \(len\) 時,對於答案串中模 \(len\) 相同的兩個位置的字母是一定相同的
那麼最小的修改次數就是將每一個模 \(len\) 同餘的可重集合都改成出現次數最多的數
這個可以 \(O(26)\) 實現插入和刪除一個數,計算代價
同時,這個代價單調遞增,所以可以 two-pointers 維護
code
// Author: xiaruize
#define ONLINE_JUDGE
#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 = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 3e3 + 10;
int n, k;
char s[N];
int cnt[N][26];
int tot[N];
int res = 0;
int cur = 0, len;
int get(int x)
{
int ret = -INF;
rep(i, 0, 25) ret = max(ret, cnt[x][i]);
return ret;
}
void add(int x)
{
cur -= tot[x % len] - get(x % len);
cnt[x % len][s[x] - 'a']++;
tot[x % len]++;
cur += tot[x % len] - get(x % len);
}
void del(int x)
{
cur -= tot[x % len] - get(x % len);
cnt[x % len][s[x] - 'a']--;
tot[x % len]--;
cur += tot[x % len] - get(x % len);
}
void solve()
{
cin >> k;
cin >> (s + 1);
n = strlen(s + 1);
for (len = 1; len <= n; len++)
{
cur = 0;
memset(cnt, 0, sizeof(cnt));
mms(tot, 0);
rep(i, 1, len - 1) add(i);
for (int l = 1, r = 1; r + len - 1 <= n; r++)
{
add(r + len - 1);
while (cur > k)
del(l++);
debug(l, r, r - l);
res = max(res, r - l);
}
}
cout << res << endl;
}
/*
bbaaaa
baaaaa
*/
#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif
signed main()
{
freopen("string.in","r",stdin);
freopen("string.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;
}
P5168. 迴文問題
manacher把每個迴文串求出來,同時在擴充的時候用並查集標記相同的點
然後對於每個極大迴文串,把這個串左側第一個向右側第一個建邊,表示這兩個不一樣
然後按照點的編號順序做染色問題即可
code
// Author: xiaruize
#define ONLINE_JUDGE
#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 = 0x3f3f3f3f;
const int MOD = 998244353;
const int N = 3e6 + 10;
int n, c;
int a[N];
int s[N << 1], res[N << 1];
vector<int> g[N];
int p[N];
int fa[N << 2];
bool vis[N];
int get(int x)
{
debug(x);
if (fa[x] == x)
return x;
return fa[x] = get(fa[x]);
}
void calc()
{
s[0] = -1;
rep(i, 1, n)
{
s[i * 2 - 1] = a[i];
s[i * 2] = -1;
}
int m = n * 2 + 2;
int mx = 0;
int mid = 0;
rep(i, 1, 2 * n - 1)
{
// cerr << "flag" << endl;
if (i <= mx)
res[i] = min(res[mid * 2 - i], res[mid] + mid - i);
else
res[i] = 1;
while (res[i] < i && i + res[i] < 2 * n && s[i + res[i]] == s[i - res[i]])
{
if (s[i + res[i]] > 0)
fa[get((i + res[i] + 1) / 2)] = get((i - res[i] + 1) / 2);
res[i]++;
}
if (res[i] + i > mx)
{
mx = res[i] + i - 1;
mid = i;
}
}
}
void solve()
{
cin >> n >> c;
rep(i, 0, n * 2) s[i] = res[i] = 0;
rep(i, 1, n)
{
g[i].clear();
vis[i] = 0;
}
rep(i, 1, n * 2 + 2) fa[i] = i;
rep(i, 1, n) cin >> a[i];
calc();
rep(i, 1, n * 2)
{
if (res[i] < i && i + res[i] < n * 2)
{
g[get((i + res[i] + 1) / 2)].push_back(get((i - res[i] + 1) / 2));
g[get((i - res[i] + 1) / 2)].push_back(get((i + res[i] + 1) / 2));
}
}
rep(i, 1, n)
{
sort(ALL(g[i]));
g[i].resize(unique(ALL(g[i])) - g[i].begin());
}
int res = 1;
rep(i, 1, n)
{
if (fa[i] == i)
{
int cnt = 0;
for (auto v : g[i])
{
cnt += vis[v];
}
// debug(i, cnt);
res = 1ll * res * (c - cnt) % MOD;
vis[i] = true;
}
}
cout << res << endl;
}
#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif
signed main()
{
freopen("palindrome.in", "r", stdin);
freopen("palindrome.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;
}
P5184. 最小生成樹機率
\(dp_{i,j,k}\) 表示選擇 \(len \leq i\) 的邊 \(j\) 條,當前MST的大小為 \(k\) 的方案數
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 = 40 + 10;
int qpow(int a, int b)
{
int res = 1;
while (b)
{
if (b & 1)
res = res *a % MOD;
a = a* a % MOD;
b >>= 1;
}
return res;
}
int n, m;
int ps[N];
int c[N][N], dp[N][N][N * N], f[N][N][N * N];
void solve()
{
cin >> n >> m;
rep(i, 0, n)
{
c[i][0] = c[i][i] = 1;
rep(j, 1, i - 1)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
}
rep(i, 0, m)
{
cin >> ps[i];
if (i)
ps[i] += ps[i - 1];
}
f[0][1][0] = 1;
rep(i, 1, m)
{
rep(j, 1, n)
{
rep(k, j - 1, i *(j - 1))
{
dp[i][j][k] = f[i - 1][j][k];
rep(p, 1, j - 1)
{
rep(q, 0, k - i)
{
(dp[i][j][k] += f[i - 1][p][q]* dp[i][j - p][k - i - q] % MOD *c[j - 1][p - 1] % MOD* qpow(100 - ps[i - 1] + ps[0], p *(j - p)) % MOD) %= MOD;
}
}
f[i][j][k] = dp[i][j][k];
rep(p, 1, j - 1)
{
rep(q, 0, k - i)
{
f[i][j][k] = ((f[i][j][k] - f[i][p][q]* dp[i][j - p][k - i - q] % MOD *c[j - 1][p - 1] % MOD* qpow(100 - ps[i] + ps[0], p *(j - p)) % MOD) % MOD + MOD) % MOD;
}
}
}
}
}
rep(i, n - 1, m* (n - 1)) cout << f[m][n][i] *qpow(qpow(100, n* (n - 1) / 2), MOD - 2) % MOD << ' ';
}
# ifndef ONLINE_JUDGE
bool end_of_memory_use;
# endif
signed main()
{
freopen("mst.in","r",stdin);
freopen("mst.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;
}
2024.03.23
P4115. SpellCards
\(dp_{i,j}\) 表示考慮到 \(i\) ,欠 \(j\) 個往後要消除
破環成鏈 暴力做就行
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 = 55 + 10;
void chkmx(int &x, int y)
{
if (x < y)
x = y;
}
int n;
int a[N], b[N];
int dp[N][N];
int res = 0;
void calc()
{
memset(dp, 0, sizeof(dp));
int ans = 0;
rep(i, 1, n)
{
rep(j, 0, 50) dp[i][j] = dp[i - 1][max(0, j - 1)];
if (a[i] + i - 1 <= n)
chkmx(dp[i][a[i] - 1], b[i]);
rep(j, 0, i - 1)
{
rep(k, 0, 50)
{
if (i + k - (i - j) + 1 + a[i] - 1 <= n)
{
chkmx(dp[i][k - (i - j) + a[i]], dp[j][k] + b[i]);
}
}
}
rep(j, 0, 50) chkmx(ans, dp[i][j]);
}
res = max(res, ans);
}
void solve()
{
cin >> n;
rep(i, 1, n) cin >> a[i];
cin >> n;
rep(i, 1, n) cin >> b[i];
rep(i, 1, n)
{
per(j, n - 1, 1)
{
swap(a[j], a[j + 1]);
swap(b[j], b[j + 1]);
}
calc();
}
cout << res << 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;
}
P4111. HatRack
從 \(deg=2\) 的點的構造,對於一個包含子樹為滿二叉樹的點,它的左右兒子可以互換
對於每個這樣的點 \(ans \times 2\)
然後判二叉樹建議按照定義判每一層的個數
code
// Author: xiaruize
#define ONLINE_JUDGE
#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 = 50 + 10;
int n;
vector<int> g[N];
int a[N];
int ed[3];
int cnt = 0;
int res = 0;
int ct[N];
int len[N];
bool dfs(int x, int fa, int dep)
{
ct[dep]++;
if (g[x].size() == 1)
{
debug(x, dep);
if (ed[1] == -1)
{
ed[1] = dep;
}
else if (ed[2] == -1)
{
if (dep != ed[1])
{
if (abs(ed[1] - dep) > 1)
{
res = 0;
return false;
}
ed[2] = dep;
}
}
else
{
if (ed[1] != dep && ed[2] != dep)
{
res = 0;
return false;
}
}
len[x] = 1;
return true;
}
bool flag = true;
len[x] = -1;
for (auto v : g[x])
{
if (v == fa)
continue;
bool tmp = dfs(v, x, dep + 1);
if (!flag && !tmp)
{
res = 0;
return false;
}
flag &= tmp;
if (len[x] == -1)
len[x] = len[v] + 1;
flag &= (len[x] == len[v] + 1);
}
flag &= (g[x].size() == 3 || fa == 0);
if (flag)
res *= 2;
return flag;
}
void solve()
{
cin >> n;
rep(i, 1, n) cin >> a[i];
cin >> n;
rep(i, 1, n)
{
int v;
cin >> v;
g[v].push_back(a[i]);
g[a[i]].push_back(v);
cerr << v << ' ' << a[i] << endl;
}
if (n == 1)
{
cout << "2" << endl;
return;
}
rep(i, 1, n + 1)
{
if (g[i].size() > 3 || g[i].empty())
{
cout << "0" << endl;
return;
}
cnt += (g[i].size() == 2);
}
if (cnt > 2)
{
cout << "0" << endl;
return;
}
int ans = 0;
rep(i, 1, n + 1)
{
if (g[i].size() == 2)
{
mms(ct, 0);
res = 1;
mms(len, 0);
ed[2] = ed[1] = -1;
dfs(i, 0, 1);
int p = 1;
rep(i, 1, __lg(n + 1))
{
if (ct[i] != p)
{
res = 0;
}
p *= 2;
}
ans += res;
debug(res);
}
}
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;
}
P4513. TreeCount
\(dp_{x,3}\) 表示考慮到 \(x\) 號點,這個點不可以向上,可以向上,不選擇的方案數
對於每個點做一個揹包dp統計一下連線了幾個點即可
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 = 112901989;
const int N = 50 + 10;
int n;
char s[N][N];
int dp[N][3];
void calc(int x, int fa, int val)
{
int tmp[N], t[N];
mms(tmp, 0);
mms(t, 0);
tmp[0] = 1;
dp[x][2] = 1;
rep(v, 1, n)
{
if (s[x][v] == 'Y' && v != fa && v != x)
{
calc(v, x, val);
mms(t, 0);
per(i, val, 0)
{
if (i)
(t[i] += dp[v][1] * tmp[i - 1] % MOD) %= MOD;
(t[i] += tmp[i] * dp[v][2] % MOD) %= MOD;
}
// debug(x, v, val, t, tmp);
rep(i, 0, val) tmp[i] = t[i];
(dp[x][2] *= (dp[v][0] + dp[v][1] + dp[v][2]) % MOD) %= MOD;
}
}
// debug(x, tmp);
rep(i, 0, val - 1)(dp[x][1] += tmp[i]) %= MOD;
dp[x][0] = tmp[val];
// debug(x, dp[x]);
}
void solve()
{
cin >> n;
rep(i, 1, n) cin >> (s[i] + 1);
// calc(1, 0, 1);
// cout << dp[1][1] + dp[1][0] + dp[1][2] << ' ';
rep(i, 0, n - 1)
{
mms(dp, 0);
calc(1, 0, i);
cout << (dp[1][1] + dp[1][0] + dp[1][2]) % MOD << ' ';
}
}
#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;
}
P4114. CheckerFreeness
題目等價於找到一對端點同色的線段使得這兩個線段相交
暴力判斷即可,有小於 \(\frac{1}{4}\) 常數
code
// Author: xiaruize
#define ONLINE_JUDGE
#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 = 250 + 10;
int read(int *a)
{
string tmp;
getline(cin, tmp);
int _ = 0;
for (char c : tmp)
if (isdigit(c))
_ = _ * 10 + c - '0';
string s;
for (int i = 1; i <= _; ++i)
{
string t;
getline(cin, t);
while (t.size() && t.back() != ' ' && !isdigit(t.back()))
t.pop_back();
s += t;
}
int cnt = 0, cur = 0;
for (char c : s)
if (c == ' ')
a[++cnt] = cur, cur = 0;
else
cur = cur * 10 + c - '0';
a[++cnt] = cur, cur = 0;
return cnt;
}
int n, m;
struct vect
{
int x, y;
} a[N], b[N];
vect operator-(vect a, vect b)
{
return {a.x - b.x, a.y - b.y};
}
int operator*(vect a, vect b)
{
return a.x * b.y - a.y * b.x;
}
void solve()
{
int t1[250], t2[250];
n = read(t1), read(t2);
for (int i = 1; i <= n; ++i)
a[i] = {t1[i], t2[i]};
m = read(t1), read(t2);
for (int i = 1; i <= m; ++i)
b[i] = {t1[i], t2[i]};
rep(i, 1, n)
{
rep(j, i + 1, n)
{
vector<vect> l, r;
rep(k, 1, m)
{
int v = (b[k] - a[i]) * (a[j] - a[i]);
if (v < 0)
l.push_back(b[k]);
else if (v > 0)
r.push_back(b[k]);
}
for (auto x : l)
{
for (auto y : r)
{
int p = (x - a[i]) * (a[i] - y), q = (y - a[j]) * (a[j] - x);
if (((x - a[i]) * (a[i] - y)) && ((p > 0 && q > 0) || (p < 0 && q < 0)))
{
debug(a[i].x, a[i].y, a[j].x, a[j].y, x.x, x.y, y.x, y.y);
debug(p, q);
NO;
return;
}
}
}
}
}
YES;
}
#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;
}
P4675. CharacterBoard
當列舉了 \(len\),考慮將這個矩陣對應到原串上
- 如果一個點被限制兩次,且兩次限制不同,\(ans=0\)
- 否則 \(ans=26^{len-k}\) ,\(k\) 為被限制的點的個數
但是 \(1e9\) 是不可以列舉的
考慮什麼情況下會出現一個點被限制超過一次的情況,這樣的情況只會發生在 \(len\) 為大小的因子時
所以可能得 \(len\) 只有 \(O(w)\) 個,這就可以列舉了
而不出現重複的 \(len\) 的貢獻是一段等比序列,直接求和即可
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 = 1000000009;
const int N = 2e5 + 10;
int qpow(int a, int b)
{
int res = 1;
while (b)
{
if (b & 1)
res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
int n, m;
string s[15];
int w, a, b;
vector<int> vec;
map<int, char> mp;
void calc()
{
rep(i, 0, n - 1)
{
rep(j, 1 - m, m - 1)
{
int x = w * i + j;
if (x <= 0)
continue;
rep(v, 1, x)
{
if (v * v > x)
break;
if (x % v != 0)
continue;
vec.push_back(v);
if (v * v != x)
vec.push_back(x / v);
}
}
}
sort(ALL(vec));
vec.resize(unique(ALL(vec)) - vec.begin());
// debug(vec);
}
void solve()
{
cin >> n;
rep(i, 0, n - 1) cin >> s[i];
m = s[0].size();
cin >> w >> a >> b;
calc();
int res = 0;
for (auto v : vec)
{
if (v > w)
break;
mp.clear();
if (v >= n * m)
res = (res - qpow(26, v - n * m) + MOD) % MOD;
bool flag = true;
rep(i, 0, n - 1)
{
rep(j, 0, m - 1)
{
int p = ((a + i) * w + b + j) % v;
if (!mp.count(p))
mp[p] = s[i][j];
if (mp[p] != s[i][j])
{
flag = false;
break;
}
}
}
if (flag)
res = (res + qpow(26, v - mp.size())) % MOD;
}
if (w >= n * m)
res = (res + (qpow(26, w - n * m + 1) - 1) * qpow(25, MOD - 2) % MOD) % MOD;
cout << res << 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;
}