#include
#include
int main () {
int a, b, n;
scanf("%d%d%d", &a, &b, &n);
auto ans = 1 + 2 * ((n - b + b - a - 1) / (b - a));
printf("%d\n", ans);
}
按 x x x排序后,对于 s i n ( x ) sin(x) sin(x),DP找LIS就行(但是直接找5w长度的会飞,于是找2.5w长度的,但是要求最开始的 s i n ( x ) sin(x) sin(x)要大于0,那么可以根据 s i n ( x ) sin(x) sin(x)的性质,就可以翻回来,得到5w长度的。
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main () {
const int N = 25000;
const int CNT = 8000000;
const double EPS = 1e-12;
using Pr = std::pair<double, int>;
auto v = std::vector<Pr>(CNT);
int x = ~0x7FFFFFFF;
for (auto &p: v) {
double s;
while ((s = sin((double)x)) > -EPS)
x += 2;
p = { s, x };
++x;
}
assert(x < 0);
auto ss = std::vector<Pr>();
auto fa = std::vector<int>(CNT);
ss.reserve(N);
for (int i = 0; i < CNT; ++i) {
auto it = std::lower_bound(
std::begin(ss),
std::end(ss),
v[i],
[](Pr const &a, Pr const &b) { return a.first < b.first; }
);
// fprintf(stderr, "> %d/%d\n", (int)(it - std::begin(ss)), (int)ss.size());
fa[i] = (it != std::begin(ss) ? it[-1].second : -1);
if (it == ss.end())
ss.push_back({ v[i].first, i });
else
*it = { v[i].first, i };
if (ss.size() == N)
break;
}
int imx = ss.back().second;
ss.clear();
for (int i = imx; i != -1; i = fa[i])
ss.push_back(v[i]);
std::reverse(std::begin(ss), std::end(ss));
for (int i = 1; i < N; ++i)
assert(sin((long double)ss[i - 1].second) < sin((long double)ss[i].second));
assert(ss.size() == N);
auto chk = std::vector<int>();
int n;
scanf("%d", &n);
if (n < N) {
for (int i = 0; i < n; ++i)
printf("%d\n", ss[i].second);
} else {
for (int i = 0; i < N; ++i) {
printf("%d\n", ss[i].second);
chk.push_back(ss[i].second);
}
n -= N;
for (int i = 0; i < n; ++i) {
printf("%d\n", -ss[ss.size() - 1 - i].second);
chk.push_back(-ss[ss.size() - 1 - i].second);
}
for (int i = 1; i < (int)chk.size(); ++i) {
assert(sin((long double)chk[i - 1]) < sin((long double)chk[i]));
// fprintf(stderr, "%d\n", i);
assert(chk[i - 1] < chk[i]);
}
}
return 0;
}
考虑把一些边加上,然后欧拉路就行。
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using pii = pair<int, int>;
int const N = 105;
int const M = N * N;
set<pii> mp[N][N];
multiset<pii> mp2[N][N];
int du[N][N];
int a[N][N];
bool vis[N][N][4];
int n, m;
void link(int x, int y) {
mp[x][y].insert({ x + 1, y + 1 });
mp[x + 1][y].insert({ x, y + 1 });
mp[x][y + 1].insert({ x + 1, y });
mp[x + 1][y + 1].insert({ x, y });
mp2[x][y].insert({ x + 1, y });
mp2[x + 1][y].insert({ x, y });
mp2[x][y + 1].insert({ x + 1, y + 1 });
mp2[x + 1][y + 1].insert({ x, y + 1 });
}
bool in_map(pii const& p) {
if (p.first < 0 || p.first > n)
return 0;
if (p.second < 0 || p.second > m)
return 0;
return 1;
}
void dfs(pii s, vector<pii>& ans, bool f) {
if (f == 0) {
for (; ;) {
if (mp[s.first][s.second].size() == 0u)
break;
auto p = *mp[s.first][s.second].begin();
mp[s.first][s.second].erase(p);
mp[p.first][p.second].erase(s);
//fprintf(stderr, "> %d %d -> %d %d\n", s.first, s.second, p.first, p.second);
dfs(p, ans, f ^ 1);
ans.push_back(p);
}
} else {
auto& tmp = mp2[s.first][s.second];
for (; ;) {
if (tmp.size() == 0u)
break;
auto p = *tmp.begin();
tmp.erase(tmp.find(p));
auto tmp2 = mp2[p.first][p.second];
tmp2.erase(tmp2.find(s));
//fprintf(stderr, "> %d %d -> %d %d\n", s.first, s.second, p.first, p.second);
dfs(p, ans, f ^ 1);
ans.push_back(p);
}
}
}
int main() {
scanf("%d%d", &m, &n);
for (int i = 0; i < n; ++i) {
static char s[N];
scanf("%s", s);
for (int j = 0; j < m; ++j)
if (s[j] == 'X') {
a[i][j] = 1;
link(i, j);
}
}
pii s = { -1, -1 };
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= m; ++j)
if (mp2[i][j].size() && s == pii{ -1, -1 })
s = { i, j };
auto ans = vector<pii>();
dfs(s, ans, 1);
printf("%d\n", ans.size() - 1u);
for (auto const& p : ans)
printf("%d %d\n", p.second, p.first);
}
#include
#include
#include
#include
#include
#include
struct Graph {
int n;
std::vector<std::vector<int>> to;
mutable std::vector<int> dis, fa;
Graph (int n_): n(n_), to(n_), dis(n), fa(n) {}
void adde (int a, int b) {
to[a].push_back(b);
}
void bfs (int ibeg) const {
const int INF = std::numeric_limits<int>::max();
std::fill(std::begin(dis), std::end(dis), INF);
std::fill(std::begin(fa), std::end(fa), 0);
auto q = std::queue<int>();
q.push(ibeg);
dis[ibeg] = 0;
fa[ibeg] = ibeg;
while (!q.empty()) {
int c = q.front();
q.pop();
for (int nxt: to[c])
if (dis[nxt] == INF) {
dis[nxt] = dis[c] + 1;
fa[nxt] = c;
q.push(nxt);
}
}
}
int farthest (int ibeg, std::vector<int> const &enable) const {
bfs(ibeg);
return *std::max_element(
std::begin(enable),
std::end(enable),
[&](int const &a, int const &b) { return dis[a] < dis[b]; }
);
}
int mid (int ibeg, std::vector<int> const &enable) const {
int c = farthest(ibeg, enable);
int d = dis[c];
if (d & 1)
return -1;
d /= 2;
while (d--)
c = fa[c];
return c;
}
bool check (int ibeg, std::vector<int> const &enable) const {
bfs(ibeg);
for (int c: enable)
if (dis[c] != dis[enable[0]])
return false;
return true;
}
};
int main () {
int n, k;
scanf("%d%d", &n, &k);
auto g = Graph(n);
for (int i = 1; i < n; ++i) {
int a, b;
scanf("%d%d", &a, &b);
--a, --b;
g.adde(a, b);
g.adde(b, a);
}
auto enable = std::vector<int>(k);
int any;
for (int i = 0; i < k; ++i) {
scanf("%d", &enable[i]);
any = --enable[i];
}
if (k == 1) {
puts("YES\n1");
} else {
any = g.farthest(any, enable);
// fprintf(stderr, "> %d\n", any);
any = g.mid(any, enable);
// fprintf(stderr, "> %d\n", any);
if (any != -1 && g.check(any, enable)) {
printf("YES\n%d\n", any + 1);
} else {
puts("NO");
}
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int const N = 200005;
struct ques {
int v, id;
int ans;
} q[N];
int qn;
bool cmp_v(ques const& x, ques const& y) {
return x.v < y.v;
}
bool cmp_id(ques const& x, ques const& y) {
return x.id < y.id;
}
int a[N];
int sum[N];
int n;
int get_r(int i, int lim) {
int ret = upper_bound(sum + 1, sum + n + 1, sum[i] + lim) - sum;
--ret;
assert(sum[ret] <= sum[i] + lim);
return ret;
}
int calc(int lim) {
int ret = 0, l = 0;
for (int i = 1; i <= n; ++i) {
int r = get_r(l, lim);
if (r <= l)
return -1;
++ret;
l = r;
if (l == n)
break;
}
return ret;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
sum[i] = sum[i - 1] + a[i];
}
scanf("%d", &qn);
for (int i = 1; i <= qn; ++i) {
scanf("%d", &q[i].v);
q[i].id = i;
}
sort(q + 1, q + qn + 1, cmp_v);
int anss = 0;
for (int i = 1; i <= qn; ++i) {
if (i == 0 || q[i].v != q[i - 1].v)
anss = calc(q[i].v);
q[i].ans = anss;
}
sort(q + 1, q + qn + 1, cmp_id);
for (int i = 1; i <= qn; ++i)
if (q[i].ans >= 0)
printf("%d\n", q[i].ans);
else
puts("Impossible");
}
#include
using namespace std;
const int maxn=1005,INF=0x7FFFFFFF;
typedef pair <int,int> P;
int n,ansx,ansy,X[maxn],Y[maxn],H[maxn];
P jiao(P A,P B)
{
int L=max(A.first,B.first),R=min(A.second,B.second);
if (L>R) return P(INF,INF); else return P(L,R);
}
bool check(int key)
{
P resX=P(-INF,INF),resY=P(-INF,INF);
for (int i=1,del;i<=n;i++)
{
del=key-H[i];
if (del<0) return false;
resX=jiao(resX,P(X[i]-del,X[i]+del));
resY=jiao(resY,P(Y[i]-del,Y[i]+del));
if (resX.first==INF || resY.first==INF) return false;
}
int x=resX.first,y=resX.second,z=resY.first,w=resY.second;
//printf(">>>>>> %d : %d %d %d %d\n",key,x,y,z,w);
ansx=x;
ansy=z;
return true;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d%d",&X[i],&Y[i],&H[i]);
int L=0,R=300000005,mid;
while (L+1<R)
{
mid=L+R>>1;
if (check(mid)) R=mid; else L=mid;
}
check(R);
printf("%d %d %d",ansx,ansy,R);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int const N = 505;
int a[N][N];
int ans[N][N];
int n;
int main() {
scanf("%d", &n);
static char s[N];
for (int i = 1; i <= n; ++i) {
scanf("%s", s + 1);
for (int j = 1; j <= n; ++j)
a[i][j] = s[j] - '0';
}
for (int k = n; k >= 1; --k) {
for (int j = k + 1; j <= n; ++j) {
int sum = 0;
for (int i = k + 1; i < j; ++i)
sum += ans[k][i] * a[i][j];
sum %= 10;
assert(sum == a[k][j] || (sum + 1) % 10 == a[k][j]);
if (sum != a[k][j])
ans[k][j] = 1;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j)
printf("%d", ans[i][j]);
putchar('\n');
}
}
最开始以为按顺序每个都直接让对应字母的矩形最大就好了,没想到WA on test40,然后搞出了反例,发现确实有些情况是不行的。然后random_shuffle了一下填充顺序就过了(emmmmm
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using Mat = std::vector<std::string>;
void solve_fill (int n, int m, Mat &mat, char ch) {
using Pr = std::pair<int, int>;
Pr p = { -1, -1 };
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (mat[i][j] == ch)
p = { i, j };
if (p.first == -1)
return;
using Mxh = std::vector<std::vector<int>>;
Mxh mxh = Mxh(n, std::vector<int>(m, 0));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (mat[i][j] == '.' || mat[i][j] == ch)
mxh[i][j] = (i == 0 ? 0 : mxh[i - 1][j]) + 1;
int mx = 0;
std::pair<Pr, Pr> ans;
for (int i = 0; i < n; ++i) {
auto ss = std::stack<int>();
for (int j = 0; j <= m; ++j) {
int curmx = j == m ? 0 : mxh[i][j];
while (!ss.empty() && mxh[i][ss.top()] >= curmx) {
int h = mxh[i][ss.top()];
ss.pop();
// if (j > 0) {
int prev = ss.empty() ? -1 : ss.top();
int w = j - prev - 1;
// if (ch == 'L' && i == 5 && j == 5) {
// fprintf(stderr, "ch=%c h=%d w=%d i=%d j=%d\n", ch, h, w, i, j);
// fprintf(stderr, "prev=%d mx=%d p.x=%d p.y=%d\n", prev, mx, p.first, p.second);
// }
if (prev < p.second && p.second < j && i - h < p.first && p.first <= i) {
if (h * w > mx) {
ans = { { i - h + 1, prev + 1 }, { i, j - 1 } };
mx = h * w;
// if (ch == 'L')
// fprintf(stderr, "up ch=%c h=%d w=%d\n", ch, h, w);
}
}
}
ss.push(j);
}
}
// return;
for (int i = ans.first.first; i <= ans.second.first; ++i)
for (int j = ans.first.second; j <= ans.second.second; ++j)
if (mat[i][j] == '.')
mat[i][j] = ch - 'A' + 'a';
}
int main () {
std::ios::sync_with_stdio(false);
int n, m;
std::cin >> n >> m;
auto mat = Mat(n, std::string());
for (auto &row: mat)
std::cin >> row;
solve_fill(n, m, mat, 'A');
auto rng = std::mt19937(456328751);
std::string ord = "BCDEFGHIJKLMNOPQRSTUVWXYZ";
decltype(mat) mat2;
for (;;) {
std::shuffle(std::begin(ord), std::end(ord), rng);
mat2 = mat;
for (char ch: ord)
solve_fill(n, m, mat2, ch);
bool orz = false;
for (int i = 0; i < n && !orz; ++i)
for (int j = 0; j < m; ++j)
if (mat2[i][j] == '.') {
orz = true;
break;
}
if (!orz)
break;
}
for (auto &row: mat2)
std::cout << row << '\n';
return 0;
}
考虑如果直接枚举 i i i和 j j j开始的后缀 ( i < j ) (i < j) (i<j),那么这两个后缀构成的答案是什么。显然就是
j + L C P ( i , j ) − i j − i = 1 + L C P ( i , j ) j − i \frac{j + LCP(i, j) - i}{j-i} = 1 + \frac{LCP(i,j)}{j - i} j−ij+LCP(i,j)−i=1+j−iLCP(i,j)
那么考虑一下反串建SAM,因为LCA处可以统计答案,那么直接dsu on tree就行
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define SZ(x) ((int)(x).size())
int const N = 400005;
int sam_sz[N], par[N], mx[N], one[N];
bool tag[N];
int sam_cnt, sam_last;
map<int, int> ch[N];
int n;
string s;
void SAM_init() {
sam_cnt = sam_last = 1;
}
int SAM_extend(int x, int pos) {
int p, q, np, nq;
p = sam_last;
sam_last = np = ++sam_cnt;
one[np] = pos;
mx[np] = mx[p] + 1;
sam_sz[np] = 1;
tag[np] = 1;
for (; p && ch[p].find(x) == ch[p].end(); p = par[p])
ch[p][x] = np;
if (p == 0)
par[np] = 1;
else {
q = ch[p][x];
if (mx[q] == mx[p] + 1)
par[np] = q;
else {
nq = ++sam_cnt;
mx[nq] = mx[p] + 1;
ch[nq] = ch[q];
par[nq] = par[q];
one[nq] = one[q];
par[q] = par[np] = nq;
for (; ch[p][x] == q; p = par[p])
ch[p][x] = nq;
}
}
return sam_last;
}
vector<int> G[N];
void addedge(int x, int y) {
G[x].emplace_back(y);
}
int sam_t[N], up[N];
void SAM_suffixTree() {
static int c[257];
memset(c, 0, sizeof(c));
for (int i = 1; i <= sam_cnt; ++i)
up[i] = s[one[i] - mx[par[i]]];
for (int i = 1; i <= sam_cnt; ++i)
c[up[i]]++;
for (int i = 1; i <= 256; ++i)
c[i] += c[i - 1];
for (int i = 1; i <= sam_cnt; ++i)
sam_t[c[up[i]]--] = i;
for (int i = 1; i <= sam_cnt; ++i)
addedge(par[sam_t[i]], sam_t[i]);
}
int siz[N], son[N];
void dfs(int x) {
siz[x] = 1;
for (auto y : G[x]) {
dfs(y);
siz[x] += siz[y];
if (son[x] == 0 || siz[y] > siz[son[x]])
son[x] = y;
}
}
int fz = 0, fm = 1;
void update_ans(int i, int j, int A) {
int tfz = A, tfm = j - i;
if (1ll * fz * tfm < 1ll * tfz * fm) {
fz = tfz;
fm = tfm;
}
}
void update(int p, set<int>& se, int A) {
auto it = se.upper_bound(p);
if (it != se.end())
update_ans(p, *it, A);
if (it != se.begin()) {
--it;
update_ans(*it, p, A);
}
se.insert(p);
}
void solve(int x, set<int>& se) {
//cerr << "in : " << x << '\n';
if (son[x])
solve(son[x], se);
if (tag[x])
update(one[x], se, mx[x]);
for (auto y : G[x])
if (y != son[x]) {
auto ts = set<int>();
solve(y, ts);
//cerr << "end : " << x << " -> " << y << '\n';
for (auto t : ts)
update(t, se, mx[x]);
}
}
int main() {
cin >> s;
n = s.size();
SAM_init();
reverse(s.begin(), s.end());
for (int i = 0; i < n; ++i)
sam_last = SAM_extend(s[i] - 'a', i);
SAM_suffixTree();
dfs(1);
auto ts = set<int>();
solve(1, ts);
fz += fm;
int gcd = __gcd(fz, fm);
fz /= gcd;
fm /= gcd;
cout << fz << '/' << fm << '\n';
}
#include
#include
#include
#include
#include
using namespace std;
int const N = 2005;
int a[N];
int tot1[N], tot2[N];
int main() {
int T;
scanf("%d", &T);
auto mp = map<int, int>();
while (T--) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
int ans = 0;
for (int j = 1; j <= n; ++j) {
mp.clear();
int m1 = 0, m2 = 0;
for (int i = 1; i < j; ++i)
tot1[m1++] = a[j] - a[i];
for (int k = j + 1; k <= n; ++k)
tot2[m2++] = a[k] - a[j];
sort(tot1, tot1 + m1);
sort(tot2, tot2 + m2);
int p = 0, num = 0;
for (int i = 0; i < m1; ++i) {
if (i == 0 || (tot1[i] != tot1[i - 1])) {
num = 0;
while (p < m2 && tot2[p] <= tot1[i]) {
if (tot2[p] == tot1[i])
++num;
++p;
}
}
ans += num;
}
}
printf("%d\n", ans);
}
}