#include
#include
using namespace std;
int const N = 100005;
int a[N], dfn[N];
int mx[N], mi[N];
void update(int x) {
mx[x] = max(mx[x], dfn[x]);
mi[x] = min(mi[x], dfn[x]);
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
a[i] = i;
dfn[i] = i;
mx[i] = mi[i] = i;
}
for (int i = 1; i <= m; ++i) {
int x;
scanf("%d", &x);
if (dfn[x] != 1) {
int pre = a[dfn[x] - 1];
dfn[x] = dfn[x] - 1;
dfn[pre] = dfn[pre] + 1;
swap(a[dfn[x]], a[dfn[pre]]);
update(x);
update(pre);
}
}
for (int i = 1; i <= n; ++i)
printf("%d %d\n", mi[i], mx[i]);
}
#include
#define LL long long
using namespace std;
const int maxn=500005,maxm=8005;
int n,m,val[maxm];
bool boo[maxn];
LL ans;
int work(int key)
{
int res=0,cnt=0;
for (int L=1,R=m;L<=R;L++)
{
while (L<R && val[L]+val[R]<=key) R--,cnt++;
if (cnt) cnt--;
res++;
}
return res+(cnt+1)/2;
}
bool cmp(int A,int B) { return A>B; }
int main()
{
scanf("%d%d",&n,&m);
for (int i=1,x;i<=n;i++)
{
scanf("%d",&x);
val[x]++;
}
sort(val+1,val+1+m,cmp);
for (int i=1;i<m;i++)
for (int j=i+1;j<=m;j++)
boo[val[i]+val[j]]=true;
ans=(LL)val[1]*work(val[1]);
for (int i=val[1]+1;i<=val[1]+val[2];i++)
if (boo[i]) ans=min(ans,(LL)i*work(i));
printf("%lld",ans);
return 0;
}
线段树维护左端点的答案就行。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
int const N = 200005;
int const M = 200000;
ll mx[N << 2], lz[N << 2];
struct node {
ll l, r, p;
} a[N];
int n;
ll m;
vector<node> vec[N];
void pushdown(int k) {
mx[k << 1] += lz[k];
mx[k << 1 | 1] += lz[k];
lz[k << 1] += lz[k];
lz[k << 1 | 1] += lz[k];
lz[k] = 0;
}
void pushup(int k) {
mx[k] = max(mx[k << 1], mx[k << 1 | 1]);
}
void modify(int k, int l, int r, int ql, int qr, ll v) {
if (ql <= l && r <= qr) {
mx[k] += v;
lz[k] += v;
return;
}
int mid = (l + r) >> 1;
if (lz[k] != 0)
pushdown(k);
if (ql <= mid)
modify(k << 1, l, mid, ql, qr, v);
if (qr > mid)
modify(k << 1 | 1, mid + 1, r, ql, qr, v);
pushup(k);
}
ll query_ans(int k, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr)
return mx[k];
int mid = (l + r) >> 1;
ll ret = 0;
if (lz[k] != 0)
pushdown(k);
if (ql <= mid)
ret = query_ans(k << 1, l, mid, ql, qr);
if (qr > mid)
ret = max(query_ans(k << 1 | 1, mid + 1, r, ql, qr), ret);
pushup(k);
return ret;
}
int query(int k, int l, int r, ll v) {
if (l == r)
return l;
int mid = (l + r) >> 1, ret = 0;
if (lz[k] != 0)
pushdown(k);
if (mx[k << 1] == v)
ret = query(k << 1, l, mid, v);
else
ret = query(k << 1 | 1, mid + 1, r, v);
pushup(k);
return ret;
}
int main() {
ios::sync_with_stdio(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i].l >> a[i].r >> a[i].p;
vec[a[i].r].push_back(a[i]);
}
int ansl = -1, ansr = -1;
ll ans = 0;
for (int i = 1; i <= M; ++i) {
modify(1, 1, M, 1, i, -m);
for (auto p : vec[i])
modify(1, 1, M, 1, p.l, p.p);
ll anss = query_ans(1, 1, M, 1, i);
if (anss > ans) {
//fprintf(stderr, ">> %d %d\n", i, anss);
ans = anss;
ansr = i;
ansl = query(1, 1, M, ans);
}
}
if (ans == 0)
puts("0");
else {
auto sub = vector<int>();
for (int i = 1; i <= n; ++i)
if (ansl <= a[i].l && a[i].r <= ansr)
sub.push_back(i);
cout << ans << ' ' << ansl << ' ' << ansr << ' ' << sub.size() << '\n';
for (int i = 0; i < (int)sub.size(); ++i) {
cout << sub[i];
if (i + 1 == (int)sub.size())
cout << '\n';
else
cout << ' ';
}
}
}
来自coming的补题,2-sat一下
#include
#include
using namespace std;
int main() {
int s;
cin >> s;
int ans = s * 10;
for (int i = 1; i <= s; ++i)
if (s % i == 0) {
int oth = s / i;
int tmp = (i + oth) * 2;
ans = min(ans, tmp);
}
cout << ans << '\n';
}
无脑DP,注意边界x
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using ll = long long;
int const N = 200005;
int a[N], b[N];
int n, m;
ll s1[N], s2[N];
int f[N], pre[N];
void dfs(int x) {
if (x == 0)
return;
dfs(pre[x]);
printf("%d ", x);
}
bool chk(int l, int r) {
return max(s1[r], s2[r]) - min(s1[l], s2[l]) < m;
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
s1[i] = s1[i - 1] + a[i];
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &b[i]);
s2[i] = s2[i - 1] + b[i];
}
f[0] = 0;
int lim = n;
for (int i = 1, p = 0; i <= n; ++i) {
while (p < i && chk(p, i) == 0)
++p;
//assert(p < i);
if (p == i) {
lim = i;
break;
}
f[i] = f[p] + 1;
pre[i] = p;
//cerr << i << ' ' << f[i] << ' ' << pre[i] << '\n';
}
s1[n + 1] = s1[n];
s2[n + 1] = s2[n];
int ans = -1, pos = -1;
for (int i = 0, p = 1; i < lim; ++i) {
p = max(p, i);
while (p < lim && chk(i, p + 1))
++p;
ll t1 = s1[i], t2 = s2[i];
ll mi = min(t1, t2);
t1 -= mi;
t2 -= mi;
t1 += s1[p + 1] - s1[i];
t2 += s2[p + 1] - s2[i];
if (t1 < m && t2 >= m) {
ans = f[i];
pos = i;
break;
}
}
printf("%d\n", ans);
if (ans != -1) {
dfs(pos);
printf("\n");
}
}
}
#include
using namespace std;
int G,cho,a[12];
int main()
{
scanf("%d",&G);
while (G--)
{
scanf("%d",&a[0]);
a[0]++;
cho=0;
for (int i=1;i<=9;i++)
{
scanf("%d",&a[i]);
if (a[i]<a[cho]) cho=i;
}
if (cho) for (int i=0;i<=a[cho];i++) printf("%d",cho); else
{
printf("1");
for (int i=1;i<=a[0];i++) printf("0");
}
printf("\n");
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using ll = long long;
int const N = 30005;
ll a[N], b[N];
int n;
ll m;
bool chk(ll lim) {
ll ret = 0;
for (int i = 0; i <= n; ++i)
b[i] = a[i];
for (int i = 1; i <= n; ++i) {
ll can = (b[i] + b[i - 1]) / lim;
ret += can;
ll del = can * lim;
del -= b[i - 1];
if (del <= 0)
continue;
b[i] -= del;
}
return ret >= m;
}
int main() {
ios::sync_with_stdio(0);
int T;
cin >> T;
while (T--) {
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> a[i];
ll l = 1, r = 5e16, ans = 0;
while (l <= r) {
ll mid = (l + r) >> 1;
if (chk(mid)) {
ans = mid;
l = mid + 1;
} else
r = mid - 1;
}
cout << ans * m << '\n';
}
}
#include
using namespace std;
int G,A,B,C,ans;
int work(int A,int B,int C,int can)
{
if (A<B) swap(A,B);
if (A<C) swap(A,C);
can-=A-B;
can-=A-C;
if (can<=0)
return A; else
return A+(can+2)/3;
}
int main()
{
scanf("%d",&G);
while (G--)
{
scanf("%d%d%d",&A,&B,&C);
ans=work(A/2,A-A/2,C,B);
ans=min(ans,work(A,C/2,C-C/2,B));
printf("%d\n",ans);
}
return 0;
}
倍增一下,每次搞方案就行
#include
#include
#include
#include
struct Ans {
std::vector<int> xs, ys;
bool empty() const {
return xs.empty() || ys.empty();
}
};
void dup (std::vector<Ans> &ans, int n, int mx) {
int tgt = std::min(n * 2 + 1, mx);
for (auto &c: ans) {
int n1 = c.xs.size();
for (int i = 0; i < n1; ++i)
if (c.xs[i] + n + 1 <= tgt)
c.xs.push_back(c.xs[i] + n + 1);
int n2 = c.ys.size();
for (int i = 0; i < n2; ++i)
if (c.ys[i] + n + 1 <= tgt)
c.ys.push_back(c.ys[i] + n + 1);
}
Ans lblk, rblk, row, col;
for (int i = n + 2; i <= tgt; ++i)
lblk.xs.push_back(i);
for (int i = 1; i <= n; ++i)
lblk.ys.push_back(i);
if (!lblk.empty())
ans.push_back(lblk);
for (int i = 1; i <= n; ++i)
rblk.xs.push_back(i);
for (int i = n + 2; i <= tgt; ++i)
rblk.ys.push_back(i);
if (!rblk.empty())
ans.push_back(rblk);
row.xs.push_back(n + 1);
for (int i = 1; i <= tgt; ++i)
if (i != n && i != n + 1)
row.ys.push_back(i);
if (!row.empty())
ans.push_back(row);
for (int i = 1; i <= tgt; ++i)
if (i != n + 1 && i != n + 2)
col.xs.push_back(i);
col.ys.push_back(n + 1);
if (!col.empty())
ans.push_back(col);
}
int main () {
// freopen("out", "w", stdout);
int n;
scanf("%d", &n);
// n = 5000;
int i = 2;
auto ans = std::vector<Ans>();
ans.push_back(Ans { {1}, {2} });
while (i < n) {
dup(ans, i, n);
i = std::min(i * 2 + 1, n);
}
printf("%d\n", (int)ans.size());
for (auto &c: ans) {
printf("%d", (int)c.xs.size());
for (auto &x: c.xs)
printf(" %d", x);
printf("\n%d", (int)c.ys.size());
for (auto &y: c.ys)
printf(" %d", y);
putchar('\n');
}
// fprintf(stderr, "%d\n", (int));
return 0;
}
虽然确实很傻逼但是有坑(,不能随便把一个连通块的某条边改过去,因为有可能不小心改了桥边x
#include
#include
#include
#include
#include
#include
struct Graph {
struct E {
int idx;
int to;
};
int n;
std::vector<std::vector<E>> to;
std::vector<int> vis;
std::vector<int> eind, ind;
Graph (int n_): n(n_), to(n), vis(n, -1), eind(n, -1), ind(n, 0) {}
void adde (int idx, int a, int b) {
to[a].push_back(E { idx, b });
++ind[b];
eind[b] = idx;
// fprintf(stderr, "%d -> %d\n", a, b);
}
struct Ans {
int idx;
int from, to;
};
Ans dfs (int c, int fa, int ibeg) {
// fprintf(stderr, "in (c=%d fa=%d ibeg=%d)\n", c, fa, ibeg);
vis[c] = ibeg;
Ans ret = { -1, -1, -1 };
for (auto &e: to[c]) {
//fprintf(stderr, "e> to=%d\n", e.to);
if (e.to == fa) {
fa = -1;
} else if (vis[e.to] == ibeg) {
ret = { e.idx, e.to, 0 };
} else if (vis[e.to] == -1) {
auto nxt = dfs(e.to, c, ibeg);
if (ret.idx == -1) {
ret = nxt;
}
}
}
//fprintf(stderr, "ret (c=%d) %d %d %d\n", c, ret.idx, ret.from, ret.to);
return ret;
}
std::vector<Ans> solve () {
int ifst = 0;
dfs(0, -1, 0);
auto blks = std::vector<Ans>(n, Ans { -1, -1, -1 });
for (int i = 1; i < n; ++i)
if (vis[i] == -1) {
auto cur = dfs(i, -1, i);
//fprintf(stderr, ">1 i=%d %d %d\n", i, cur.idx, cur.from);
if (cur.idx == -1)
blks[i].idx = -2;
else
blks[i] = cur;
}
/*&
for (int i = 0; i < n; ++i)
fprintf(stderr, "(%d,%d) ", blks[i].idx, blks[i].from);
fprintf(stderr, " <
for (int i = 1; i < n; ++i)
if (vis[i] >= 1 && ind[i] == 1 && blks[vis[i]].idx == -2) {
//fprintf(stderr, ">2 %d %d\n", eind[i], i);
blks[vis[i]] = { eind[i], i, ifst };
}
auto ret = std::vector<Ans>();
for (auto &c: blks)
if (c.idx != -1)
ret.push_back(c);
return ret;
}
};
int main () {
int t;
scanf("%d", &t);
while (t--) {
int m;
scanf("%d", &m);
auto hm = std::vector<int>();
auto es = std::vector<std::pair<int, int>>(m);
for (auto &e: es) {
scanf("%d%d", &e.first, &e.second);
hm.push_back(e.first);
hm.push_back(e.second);
}
std::sort(hm.begin(), hm.end());
hm.erase(std::unique(hm.begin(), hm.end()), hm.end());
auto g = Graph(hm.size());
for (int i = 0; i < (int)es.size(); ++i) {
int a = std::lower_bound(hm.begin(), hm.end(), es[i].first) - hm.begin();
int b = std::lower_bound(hm.begin(), hm.end(), es[i].second) - hm.begin();
g.adde(i, a, b);
g.adde(i, b, a);
}
auto ans = g.solve();
printf("%d\n", (int)ans.size());
for (auto &c: ans) {
int a = hm[c.from], b = hm[c.to];
printf("%d %d %d\n", c.idx + 1, a, b);
}
}
return 0;
}