LOJ刷题记录:SHOI2016(2036-2041)
来源:互联网 发布:剑灵n卡优化设置2017 编辑:程序博客网 时间:2024/06/09 16:26
LOJ刷题记录:SHOI2016(2036-2041)
loj#2036. 「SHOI2015」自动刷题机
直接二分就好了。
#include <bits/stdc++.h>using namespace std;const int MAXN = 200005;int x[MAXN];int n, k;int calc(long long N){ long long ans = 0; int cnt = 0; for (int i = 1; i <= n; i++) { // cerr << x[i] << " "; ans += x[i]; if (ans < 0) ans = 0; if (ans >= N) cnt++, ans = 0; } // cerr << endl; return cnt;}int main(){ scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d", &x[i]); long long L = 1, R = 1e18, mid; while (L <= R) { mid = L+((R-L)>>1); if (calc(mid) <= k) R = mid-1; else L = mid+1; } long long Low = R+1; L = 1, R = 1e18; while (L <= R) { mid = L+((R-L)>>1); if (calc(mid) >= k) L = mid+1; else R = mid-1; } long long Up = L-1; // cerr << calc(Up) << endl; if (calc(Up) != k || calc(Low) != k || Low > Up) puts("-1"); else cout << Low << " " << Up << endl; return 0;}
loj#2037. 「SHOI2015」脑洞治疗仪
以前做过…
#include <bits/stdc++.h>using namespace std;const int MAXN = 200005;int dat[MAXN*4], lc[MAXN*4], rc[MAXN*4], l[MAXN*4], r[MAXN*4];int change[MAXN*4], llen[MAXN*4], rlen[MAXN*4], len[MAXN*4], top = 0, root = 0;inline int new_node(int opl, int opr){ return ++top, l[top] = opl, r[top] = opr, top; }inline void pdw(int nd) // 1 nh / -1 hole{ if (!change[nd]) return; change[lc[nd]] = change[rc[nd]] = change[nd]*(lc[nd]!=0); dat[nd] = (r[nd]-l[nd]+1)*(change[nd]==1); llen[nd] = rlen[nd] = len[nd] = (r[nd]-l[nd]+1)*(change[nd]==-1); change[nd] = 0;}inline void update(int nd){ pdw(nd), pdw(lc[nd]), pdw(rc[nd]); if (l[nd] == r[nd]) { llen[nd] = rlen[nd] = len[nd] = (dat[nd]==0); return; } llen[nd] = llen[lc[nd]]+(dat[lc[nd]] == 0)*llen[rc[nd]]; rlen[nd] = rlen[rc[nd]]+(dat[rc[nd]] == 0)*rlen[lc[nd]]; len[nd] = max(max(len[lc[nd]], len[rc[nd]]), rlen[lc[nd]]+llen[rc[nd]]); dat[nd] = dat[lc[nd]]+dat[rc[nd]];}int pat[MAXN];void build(int &nd, int l, int r){ nd = new_node(l, r); if (l == r) dat[nd] = pat[r]; else build(lc[nd], l, (l+r)/2), build(rc[nd], (l+r)/2+1, r); update(nd);}void modify(int nd, int opl, int opr, int alc){ if (opl > opr) return; pdw(nd); if (opl == l[nd] && opr == r[nd]) change[nd] = alc, pdw(nd); else { int mid = (l[nd]+r[nd])/2; if (opr <= mid) modify(lc[nd], opl, opr, alc); else if (opl > mid) modify(rc[nd], opl, opr, alc); else modify(lc[nd], opl, mid, alc), modify(rc[nd], mid+1, opr, alc); pdw(lc[nd]), pdw(rc[nd]), update(nd); }}int query(int nd, int opl, int opr){ pdw(nd); if (opl == l[nd] && opr == r[nd]) return len[nd]; else { int mid = (l[nd]+r[nd])/2; pdw(lc[nd]), pdw(rc[nd]); if (opr <= mid) return query(lc[nd], opl, opr); else if (opl > mid) return query(rc[nd], opl, opr); else return max(max(query(lc[nd], opl, mid), query(rc[nd], mid+1, opr)), min(rlen[lc[nd]], mid-opl+1)+min(llen[rc[nd]], opr-mid)); }}void dfs(int nd, int tab = 0){ if (!nd) return; for (int i = 1; i <= tab; i++) putchar(' '); printf("[%d, %d], dat = %d, llen = %d, rlen = %d, len = %d, change = %d\n", l[nd], r[nd], dat[nd], llen[nd], rlen[nd], len[nd], change[nd]); dfs(lc[nd], tab+2), dfs(rc[nd], tab+2);}int query_sum(int nd, int opl, int opr){ if (opl > opr) return 0; pdw(nd); int mid = (l[nd]+r[nd])/2; if (opl == l[nd] && opr == r[nd]) return dat[nd]; else return query_sum(lc[nd], opl, min(opr, mid))+query_sum(rc[nd], max(opl, mid+1), opr);}int last_pos(int nd, int k) // in node nd, the first place to have k holes{ if (l[nd] == r[nd]) return l[nd]; pdw(nd), pdw(lc[nd]), pdw(rc[nd]); int lp = r[lc[nd]]-l[lc[nd]]+1-dat[lc[nd]]; // cerr << l[nd] << "," << r[nd] << " ; " << k << " ; " << lp << endl; if (lp >= k) return last_pos(lc[nd], k); else return last_pos(rc[nd], k-lp);}void fix(int ll, int lr, int nl, int nr){ int dt = query_sum(root, ll, lr); // cerr << "-->" << max(0, nl-1)-query_sum(root, 1, nl-1)+dt << "-" << k << endl; modify(root, ll, lr, -1); if (dt == 0) return; int k = last_pos(root, nl-1-query_sum(root, 1, nl-1)+dt); modify(root, nl, min(nr, k), 1);}inline int read(){ int a = 0, c; do c = getchar(); while (!isdigit(c)); while (isdigit(c)) a = a*10+c-'0', c = getchar(); return a;}int n, m;int main(){ n = read(), m = read(); for (int i = 1; i <= n; i++) pat[i] = 1; build(root, 1, n); for (int i = 1; i <= m; i++) { // dfs(root); int tp, l, r, u, v; tp = read(); if (tp == 0) l = read(), r = read(), modify(root, l, r, -1); else if (tp == 1) l = read(), r = read(), u = read(), v = read(), fix(l, r, u, v); else l = read(), r = read(), printf("%d\n", query(root, l, r)); // for (int j = 1; j <= n; j++) cerr<<query_sum(root, j, j)<<" "; // cerr << endl; // dfs(root); } return 0;}
loj#2038. 「SHOI2015」超能粒子炮・改
考虑
第二部分为余下的部分,也就是:
这样两部分加起来美滋滋,复杂度
#include <bits/stdc++.h>using namespace std;const int mod = 2333;int c[mod+20][mod+20], f[mod+20][mod+20];inline int lucas(long long i, long long j){ if (i < mod && j < mod) return c[i][j]; return c[i%mod][j%mod]*lucas(i/mod, j/mod)%mod;}inline int fun(long long i, long long j){ if (i < mod && j < mod) return f[i][j]; return (f[i%mod][mod-1]*fun(i/mod, (j+1)/mod-1)+lucas(i/mod, j/mod)*f[i%mod][(j+1)%mod-1])%mod;}int main(){ c[0][0] = 1; for (int i = 1; i < mod; i++) for (register int j = 0; j <= i; j++) c[i][j] = (c[i-1][j]+(j>=1)*c[i-1][j-1])%mod; for (int i = 0; i < mod; i++) { f[i][0] = 1; for (register int j = 1; j < mod; j++) f[i][j] = (f[i][j-1]+c[i][j])%mod; } // cerr << lucas(12132, 3211) << endl; int T; scanf("%d", &T); while (T--) { long long n, m; scanf("%lld%lld", &n, &m); printf("%d\n", fun(n, m)); } return 0;}
loj#2039. 「SHOI2015」激光发生器
写了一天的码农计算几何题…
这种题呀…大概是有毒
#include <bits/stdc++.h>using namespace std;const int MAXN = 105;const double eps = 1e-9;struct point { double x, y; friend point operator + (const point &a, const point &b) { return (point){a.x+b.x, a.y+b.y}; } friend point operator - (const point &a, const point &b) { return (point){a.x-b.x, a.y-b.y}; } friend point operator * (double lambda, const point &a) { return (point){lambda*a.x, lambda*a.y}; } friend double operator * (const point &a, const point &b) { return a.x*b.y-a.y*b.x; } inline double len() const { return sqrt(x*x+y*y); } inline double dot(const point &a) { return x*a.x+y*a.y; } double angel(const point &a) { return acos((x*a.x+y*a.y)/len()/a.len()); } point rot(double theta) { return (point){cos(theta)*x-sin(theta)*y, sin(theta)*x+cos(theta)*y}; }};typedef point vec;struct line { point p; vec v; inline line normal_left(const point &a) { return (line){a, v.rot(M_PI/2)}; } inline line normal_right(const point &a) { return (line){a, v.rot(-M_PI/2)}; } inline bool on_left(const point &a) { return v*(a-p) > 0; } inline bool on_right(const point &a) { return !on_left(a); } friend point operator * (const line &a, const line &b) { double lambda = b.v*(b.p-a.p)/(b.v*a.v); // cerr << " " << lambda << endl; return a.p+lambda*a.v; } bool along(const point &pt) { return (pt-p).dot(v) > eps; } inline bool on_line(const point &a) { return (a-p).dot(a-(p+v)) <= eps; }} px;int n;double lambda[MAXN];line ln[MAXN];int main(){ double a, b, c, d, x, y; scanf("%lf%lf%lf%lf", &a, &b, &c, &d); px.p = (point){a, b}, px.v = (vec){c, d}; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &x, &y); ln[i].p = (point){a, b}, ln[i].v = (point){c-a, d-b}, lambda[i] = x/y; } bool pp = 0; for (int i = 1; i <= 10; i++) { point fc; double len = 1e30; int id; for (int j = 1; j <= n; j++) { point pt = px*ln[j]; if (ln[j].on_line(pt) && px.along(pt)) { if ((pt-px.p).len() < len) fc = pt, len = (pt-px.p).len(), id = j; } } if (len >= 1e30) break; line nor = ln[id].on_left(px.p)?ln[id].normal_left(fc):ln[id].normal_right(fc); double ang = (px.p-fc).angel(nor.v); if ((px.p-fc)*nor.v < 0) ang = -ang; ang = ang+ang*lambda[id]; px = (line){fc, (px.p-fc).rot(ang)}; pp = 1; // cerr << fc.x << " " << fc.y << "," << px.v.x << " " << px.v.y << endl; printf("%d ", id); } if (pp == 0) puts("NONE"); else puts(""); return 0;}
loj#2040. 「SHOI2015」零件组装机
以前做过…如果有方案,方案唯一,直接找就好了…
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;inline int gcd(int a, int b){ return b==0?a:gcd(b, a%b); }vector<int> vec[MAXN];int n, T, m;bool solve(int L, int R){ if (L == R) return 1; if (L > R || vec[L].empty()) return 0; // if (vec[L].size() == R-L) return solve(L+1, R); int d = vec[L][vec[L].size()-1]-L, plc = -1, cnt = 0; for (int i = vec[L].size()-1; i >= 0; i--) { int tar = vec[L][i]; cnt++; if (gcd(tar-L, d) == tar-L && (R-L)/(tar-L) == cnt && R-tar+1 >= tar-L) { plc = tar; break; } } if (plc == -1) return 0; // cerr << L << " " << R << " " << plc << endl; for (int i = L; i < plc; i++) { int N = (R-i)/(plc-L); while (N) { if (vec[i][vec[i].size()-1] != i+(plc-L)*N) return 0; N--, vec[i].pop_back(); } } return solve(L, plc-1)&&solve(plc, R);}unordered_set<int> st[MAXN];int main(){ scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) vec[i].clear(); int flag = 0; for (int i = 0; i < n; i++) st[i].clear(); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); if (u == v) { flag = 1; } if (u > v) swap(u,v); if (!st[u].count(v)) { st[u].insert(v); vec[u].push_back(v); } else flag = 1; } if (flag) { puts("NO"); continue; } for (int i = 0; i < n; i++) sort(vec[i].begin(), vec[i].end()); if (solve(0, n-1)) puts("YES"); else puts("NO"); } return 0;}
阅读全文
0 0
- LOJ刷题记录:SHOI2016(2036-2041)
- LOJ刷题记录:2024-2029(SHOI2016)
- LOJ刷题记录:2000-2005(SDOI2017)
- LOJ刷题记录:2006-2011(SCOI2015)
- LOJ刷题记录:2012-2017(SCOI2016)
- LOJ刷题记录:2018-2020
- LOJ刷题记录:2030-2035(SDOI2016)
- OI刷题记录
- OI刷题记录~
- leetcode刷题记录
- 刷题记录
- 6.22刷题记录
- 7.26-刷题记录
- hdu 刷题记录
- 面试刷题记录
- 每日刷题记录
- leetcode刷题记录
- hdu刷题记录
- openCV---相机内外参标定
- 数列转换
- 垃圾收集器(二)
- 虚拟币开发专题(什么是第一代山寨币钱包(轻钱包)?)
- Linux curl命令详解
- LOJ刷题记录:SHOI2016(2036-2041)
- module——import命令(笔记)
- js闭包判断点击的元素顺序
- 第一阶段_第一部分_工具介绍
- 8_实现Serializable接口_重写equals和hashCode方法
- PHP_Apache安装
- luoguP3168 [CQOI2015]任务查询系统
- 2.6 输入/输出流
- 嵌入式处理器-2.4