C. Constructing Ranches

给一棵树,点带权,问有多少条路径的点权能构成一个严格(指有面积)的多边形。

结论:充要条件为∑ai−max⁡ai>max⁡ai\sum a_i - \max{a_i} > \max{a_i}∑ai​−maxai​>maxai​

考虑点分治, 处理出当前分治子树下所有点到分治点的路径中的权值和以及权值最大值.

然后按权值最大值排序,用树状数组计数,复杂度为O(nlog2n)O(nlog^2n)O(nlog2n).

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, ll> pil;
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
const int N = 200010;vector<int> E[N];
vector<pil> info;
int sz[N], a[N];
bool vis[N];void prepare(int u, int fa) {sz[u] = 1;for(auto &v : E[u]) {if(v == fa || vis[v]) continue;prepare(v, u);sz[u] += sz[v];}
}
void getroot(int u, int fa, int &m, int &root) {if(sz[u] * 2 < m) return;if(sz[u] < sz[root]) root = u;for(auto &v : E[u]) {if(v == fa || vis[v]) continue;getroot(v, u, m, root);}
}
void getinfo(vector<pil> &info, int u, int fa, int nowmx, ll nowsum) {nowmx = max(nowmx, a[u]), nowsum = nowsum + a[u];for(auto &v : E[u]) {if(v == fa || vis[v]) continue;getinfo(info, v, u, nowmx, nowsum);}info.emplace_back(nowmx, nowsum);
}
ll calc(int u, int root) {info.clear();int _mx = u == root ? 0 : a[root], _a = _mx;getinfo(info, u, 0, _mx, _a);
//  info.pop_back();vector<ll> dec(info.size());for(int i = 0; i < (int)info.size(); i++) {dec[i] = info[i].se - a[root];}sort(all(dec)); dec.erase(unique(all(dec)), dec.end());vector<int> bit(dec.size() + 1, 0);int L = dec.size();auto add = [&](int x) { for(; x <= L; x += x&-x) bit[x]++;};auto sum = [&](int x) { int ret = 0; for(; x; x -= x&-x) ret += bit[x]; return ret;};sort(all(info), greater<pil>());ll ret = 0;for(auto &e : info) {ret += sum(upper_bound(all(dec),e.se-a[root])-dec.begin());int idx = upper_bound(all(dec),2*e.fi-e.se)-dec.begin()+1;if(idx <= L) add(idx);}return ret;
}
ll divide(int u) {prepare(u, 0);int m = sz[u], root = u;getroot(u, 0, m, root);ll ret = calc(root, root); vis[root] = 1;
//    cout << root << ' ' << ret << '\n';
//    for(auto &e : info) cout << e.fi << ' ' << e.se << endl;for(auto &v : E[root]) {if(vis[v]) continue;ret -= calc(v, root);ret += divide(v);}return ret;
}void solve(int cas) {int n; cin >> n;for(int i = 1; i <= n; i++) E[i].clear(), vis[i] = 0;for(int i = 1; i <= n; i++) cin >> a[i];for(int i = 1, u, v; i < n; i++) {cin >> u >> v;E[u].emplace_back(v);E[v].emplace_back(u);}cout << divide(1) << '\n';
}int main() {#ifdef localfreopen("in.txt", "r", stdin);
#endifios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int _; cin >> _;for(int i = 1; i <= _; i++) solve(i);return 0;
}

E. Erasing Numbers

给一个111到nnn的排列,保证nnn一定是奇数.

每次你可以选择连续的三个数,并将三个数中的最大值和最小值删掉,删到只有最后一个数为止,

问第iii个数能否留在最后.

考虑比第iii个数大的数的个数和小的数的个数,如果能删到让两种数的个数相等,则第iii个数可以留到最后。

贪心删个数多的一边即可,复杂度O(n2)O(n^2)O(n2)。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
const int N = 5010;
int a[N], n;int go(int l, int r, int p) {if(l > r) return 0;int num1 = a[p] - 1, num2 = n - a[p];int ret = 0, sz = 0;if(num1 < num2) {for(int i = l; i <= r; i++) {if(a[i] > a[p]) {if(++sz == 3) sz -= 2, ret++;} else if(--sz == -1) sz = 0;}} else {for(int i = l; i <= r; i++) {if(a[i] < a[p]) {if(++sz == 3) sz -= 2, ret++;} else if(--sz == -1) sz = 0;}}return ret;
}void solve(int cas) {cin >> n;for(int i = 0; i < n; i++) cin >> a[i];for(int i = 0; i < n; i++) {int c1 = go(0, i - 1, i);int c2 = go(i + 1, n - 1, i);int c3 = abs(n + 1 - 2 * a[i]) / 2;if(c1 + c2 >= c3) cout << "1";else cout << "0";}cout << '\n';
}int main() {#ifdef localfreopen("in.txt", "r", stdin);
#endifios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int _; cin >> _;for(int i = 0; i < _; i++) solve(i);return 0;
}

H. Hold the Line

两种操作:

1.在xxx位置插入一个yyy;

2.查询[l,r][l,r][l,r]区间中离xxx近的yyy,输出∣x−y∣|x-y|∣x−y∣.

线段树套std::setstd::setstd::set的在线做法常数过大,考虑cdqcdqcdq分治,线段树套单调栈等离线做法.

加快读勉强卡过去.

#include<bits/stdc++.h>
using namespace std;
const int N = 1 << 19 | 7;
const int inf = 0x3f3f3f3f;
struct seg_t {#define ls o << 1
#define rs o<<1|1static int n;static void set_n(int _n) { n = _n;}struct node_t {int val;node_t() {}node_t(int _val):val(_val) {}operator int() { return val;}void init(int _val) { val = _val;}node_t operator + (const node_t &rhs) {return node_t(max(val, rhs.val));}} node[N << 1];void init() {build();}void build(int o = 1, int l = 1, int r = n) {if(!node[o].val) return;node[o].val = 0;if(l == r) return;int mid = (l + r) >> 1;build(ls, l, mid);build(rs, mid + 1, r);// node[o] = node[ls] + node[rs];}void update(int x, int v, int o = 1, int l = 1, int r = n) {if(l == r) return node[o].init(v);int mid = (l + r) >> 1;if(mid >= x) update(x, v, ls, l, mid);else update(x, v, rs, mid + 1, r);node[o] = node[ls] + node[rs];}node_t query(int ql, int qr, int o = 1, int l = 1, int r = n) {if(ql <= l && r <= qr) return node[o];node_t ret = 0; int mid = (l + r) >> 1;if(ql <= mid) ret = ret + query(ql, qr, ls, l, mid);if(qr > mid) ret = ret + query(ql, qr, rs, mid + 1, r);return ret;}
} tree;
int seg_t::n;int ans[N * 2];
struct event {int ty, l, r, h, id;bool operator < (const event&rhs)const {if(h != rhs.h) return h < rhs.h;return ty < rhs.ty;}
} E[N * 2], tE[N * 2];void work(int l, int r) {if(l == r) return;if(r - l < 200) {for(int i = l; i <= r; i++) if(E[i].ty) {for(int j = l; j < i; j++) if(!E[j].ty && E[j].h <= E[i].h) {if(E[i].l <= E[j].l && E[j].l <= E[i].r)ans[E[i].id] = min(ans[E[i].id], E[i].h - E[j].h);}}sort(E + l, E + r + 1);return;}int mid = (l + r) >> 1;work(l, mid); work(mid + 1, r);int p = l, q = mid + 1, c = l;while(q <= r) {if(p <= mid && E[p] < E[q]) {if(!E[p].ty) tree.update(E[p].l, E[p].h);tE[c++] = E[p++];} else {if(E[q].ty) {int t = tree.query(E[q].l, E[q].r);if(t) ans[E[q].id] = min(ans[E[q].id], E[q].h - t);}tE[c++] = E[q++];}}while(p <= mid) tE[c++] = E[p++];for(int i = l; i <= r; i++) E[i] = tE[i];tree.init();
}
inline char nc() {#define SZ 1000000static char buf[SZ], *p1 = buf, *p2 = buf;return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, SZ, stdin), p1 == p2) ? EOF : *p1++;
#undef SZ
}
int scan(int &x) {char c;while(!isdigit(c = nc()) && c != EOF);if(c == EOF) return c;for(x = 0; isdigit(c); c = nc())x = x * 10 + (c ^ 48);return 1;
}
template<typename ...Args>
int scan(int &x, Args&...args) {return scan(x), scan(args...);
}
void print(int x) {static char buf[21], *p2;if(x < 0) putchar('-'), print(-x);else {*(p2 = buf + 20) = '\0';if(!x) *--p2 = 48;while(x) *--p2 = x % 10 ^ 48, x /= 10;puts(p2);}
}
int main() {#ifdef localfreopen("in.txt", "r", stdin);
#endifint _; scan(_);while(_--) {int n, q; scan(n, q);for(int i = 0; i < q; i++) {ans[i] = inf;scan(E[i].ty);if(E[i].ty) scan(E[i].l, E[i].r, E[i].h);else scan(E[i].l, E[i].h), E[i].r = E[i].l;E[i].id = i;}seg_t::set_n(n);work(0, q - 1);for(int i = 0; i < q; i++) tE[E[i].id] = E[i];for(int i = 0; i < q; i++) E[i] = tE[i];for(int i = 0; i < q; i++) E[i].h = 1e9 + 1 - E[i].h;work(0, q - 1);for(int i = 0; i < q; i++) tE[E[i].id] = E[i];for(int i = 0; i < q; i++) E[i] = tE[i];for(int i = 0; i < q; i++) {if(E[i].ty) {if(ans[i] == inf) ans[i] = -1;print(ans[i]);}}}return 0;
}

I. Incoming Asteroids

两种操作:

  1. 在q[1..k](1≤k≤3)q[1..k](1\leq k \leq 3)q[1..k](1≤k≤3)个容器里插入一个值为y的元素,当这个值y在一个容器改变时,它在其他容器的值也会改变。
  2. 将第xxx个容器的值全部减yyy,若有元素的值小于000,则按插入顺序输出他们,并从容器中删除。

两种操作均强制在线。

据CJB所说,这个idea来自2018年毛营.

将yyy分成kkk份,分别插入到各个容器中,若yyy在某个容器中的值小于000则从其他容器中取出y,然后分成kkk份,重新插入到各个容器中,

每个容器用堆维护最小值,这样每次取出yyy,yyy都会至少减小原来的13\frac1331​。均摊复杂度为O(mlog⁡nlog⁡y).O(m\log n\log y).O(mlognlogy).

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int N = 200010;
int tot = 0;
vector<int> ans;
vector<int> p[N];
vector<ll> g[N];
ll del[N];
int val[N], vis[N];
struct event {ll v;int t, id;event() {}event(ll _v, int _t, int _id) { v = _v, t = _t, id = _id;}bool operator < (const event &r)const {return v > r.v;}
};
priority_queue<event> A[N];
int main() {#ifdef localfreopen("in.txt", "r", stdin);
#endifios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int n, q; cin >> n >> q;while(q--) {int op; cin >> op;if(op == 1) {int id = ++tot;int y, k; cin >> y >> k; y ^= ans.size();val[id] = y;p[id].resize(k);g[id].resize(k);y = (y + k - 1) / k;for(int i = 0; i < k; i++) {int x; cin >> x; x ^= ans.size();A[x].emplace(del[x] + y, vis[id], id);p[id][i] = x;g[id][i] = del[x];}} else {int x, y; cin >> x >> y;x ^= ans.size(), y ^= ans.size();ans.clear();del[x] += y;while(!A[x].empty() && A[x].top().v <= del[x]) {event temp = A[x].top(); A[x].pop();if(temp.t != vis[temp.id]) continue;vis[temp.id]++;ll tt = 0;for(int i = 0; i < (int) p[temp.id].size(); i++) {int x = p[temp.id][i];tt += del[x] - g[temp.id][i];}if(tt >= val[temp.id]) ans.push_back(temp.id);else {val[temp.id] -= tt;int y = (val[temp.id] + p[temp.id].size() - 1) / p[temp.id].size();for(int i = 0; i < (int) p[temp.id].size(); i++) {int x = p[temp.id][i];A[x].emplace(del[x] + y, vis[temp.id], temp.id);g[temp.id][i] = del[x];}}}cout << ans.size();sort(all(ans));for(auto &e : ans) cout << ' ' << e; cout << '\n';}}return 0;
}

J. Junior Mathematician

数位dpdpdp出线题(逃)

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int N = 5010;
char s1[N], s2[N];
int dp[N][60][60], num[N], pw10[N], n, m;
int dfs(int p, int dt, int prf, bool limit) {if(p == -1) return dt == 0;if(!limit && dp[p][dt][prf] != -1) return dp[p][dt][prf];int up = limit ? num[p] : 9, res = 0;for(int i = 0; i <= up; i++)res=(res+dfs(p-1,(dt+i*pw10[p]-i*prf%m+m)%m,(prf+i)%m,limit&&(i==up)))%mod;if(!limit) dp[p][dt][prf] = res;return res;
}
bool check(char *s) {int n = strlen(s), x = 0, sum = 0, prf = 0;for(int i = 0; i < n; i++) {x = (x * 10 + s[i] - '0') % m;sum = (sum + (s[i] - '0') * prf) % m;prf = (prf + s[i] - '0') % m;}return x == sum;
}
int solve(char *s) {int n = strlen(s);reverse(s, s + n);for(int i = 0; i < n; i++) num[i] = s[i] - '0';return dfs(n - 1, 0, 0, 1);
}int main() {#ifdef localfreopen("in.txt", "r", stdin);
#endifios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int _; cin >> _; pw10[0] = 1;while(_--) {cin >> s1 >> s2 >> m;int n = strlen(s2);memset(dp, -1, sizeof(dp[0]) * n);for(int i = 1; i <= n; i++) {pw10[i] = pw10[i - 1] * 10 % m;}int res = check(s1);res = (res + solve(s2)) % mod;res = (res + mod - solve(s1)) % mod;cout << res << '\n';}return 0;
}

2019 香(shen)港(zhen)Regional补题相关推荐

  1. 2019 Multi-University Training Contest 7 部分补题

    2019 Multi-University Training Contest 7 部分补题 这场比赛三个人一起组队,比赛期间自己感觉并没有奉献多少东西,所以补题.而且总感觉比赛到后期很乏力(没力气那种 ...

  2. [题单]多校补题 2017-2012

    仅做初步了解并筛除了不大可能会解的题目 (一般都会咕的) hard表示榜单过题人数少于50或20(大概)的题目 ****2017**** 6034 贪心 6035 树形DP OO 6038 组合数学 ...

  3. 2019暑期个人排位集训补题--思维题

    2019暑期集训思维相关补题集 CodeForces - 768B Code For 1 Gym - 100066B CodeForces - 768B Code For 1 Jon fought b ...

  4. Good Bye 2019补题记录

    Good Bye 2019补题记录 A. Card Game 题目描述 Two players decided to play one interesting card game. There is ...

  5. 2019 CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题记录

    一篇来自ACM入门者的补题记录 最近有点懒,想着还有最后一篇博客没完成,是我最大的补题动力. 不过终于在camp过去三个月的时候完成了所有的补题博客,有点欣慰,下一个目标应该是补一补一年前暑期训练的题 ...

  6. 2019寒假集训第五场(新生场)中石油补题和题解

    这场比赛本来我都出去了,然后看到老师发消息又回来了= = 然后做着做着正好mhr大佬在外面有一些事情突然没法比赛,于是就帮他交了两道题看看对不对,便于之后补题,然后还真都对了,下面是题目和解析: 问题 ...

  7. 2019暑期多校补题情况 hdu

    hdu: Ο 以补 .   未补 题号 A B C D E F G H I J K L 状态 . Ο . Ο Ο . . . . . . . 第一场: 现场: 1004:思路 1005:板子最短路+最 ...

  8. 2019 百度之星复赛 补题

    A - Diversity HDU - 6725 (树形dp) 若两个区间有交,显然可以把两个区间的值,都取在区间交集的端点的其中一个, 若没有交集的话,[l1,r1]<[l2,r2]时,取到r ...

  9. 2019/4/2UPC团队训练题解(A,B,E,G,I,K,L)加补题(C,D)

    问题 A: 篮球队选拔 时间限制: 1 Sec  内存限制: 128 MB 提交: 501  解决: 188 [提交] [状态] [命题人:外部导入] 题目描述 云南中医学院坐落于风景秀丽.四季如春的 ...

最新文章

  1. Matlab实现连通域标记算法求图像连通域
  2. java this final_Java this、final等关键字总结
  3. POI操作Excel:cell的背景颜色类型
  4. 【POJ - 1463】Strategic game (树上最小点覆盖,树形dp)
  5. C++:53---菱形继承、虚继承
  6. Python学习练习:批量移动文件
  7. 酷黑风个人主页+引导页源码
  8. 完全卸载sql2005
  9. Android进阶——深入浅出Handler(一)
  10. java解析xml工具类_通过dom4j解析XML字符串XMLDocUtil工具类转换为XML文档及获取指定根节点及指定节点路径内容代码示例...
  11. nvidia旧版驱动_NVIDIA显卡驱动曝出5个高危级别漏洞 请尽快升级最新版本
  12. Android Gallery3D源码分析(二)
  13. golang读取EXIF orientation标记
  14. 十二星座html网页设计作品,十二星座的专属设计风格
  15. iOS-内购注意 沙盒二次验证
  16. response.setHeader()的用法详解及实现文件下载过程中出现问题的分析
  17. 《OpenCv视觉之眼》Python图像处理六 :Opencv图像傅里叶变换和傅里叶逆变换原理及实现
  18. 拼多多商品发布规则|一度智信
  19. 【Java校招你不知道的那些事儿】java内推是坑吗?纯忽悠,一点用没有?
  20. 根据对数正态分布产生随机数

热门文章

  1. Symbian知识汇集
  2. 反应式编程框架设计:如何使得程序调用不阻塞等待
  3. fluent并行 linux_Ansys 14中Fluent并行计算MPI全程详解
  4. 基于Linux RHEL 5 5 安装Oracle 10g RAC
  5. consistent gets
  6. iOS模仿安卓Material Design的涟漪动画按钮
  7. 校园二手交易系统,二手交易网站,闲置物品交易系统毕业设计作品
  8. 知识图谱相关会议之观后感分享与学习总结
  9. 结合源码看《我所理解的cocos2dx-3.0》—— 字体
  10. Visual C++ 2005的现代语言特性