2017 ACM/ICPC Asia Regional Shenyang Online 记录
这场比赛全程心态爆炸……
开场脑子秀逗签到题WA了一发。之后0贡献。
前期状态全无 H题想复杂了,写了好久样例过不去。
然后这题还是队友过的……
后期心态炸裂,A题后缀数组理解不深,无法特判k = 1时的情况。
然后也没有心思读题了,心静不下来。
Problem B
$ans = k(n - k + 1)$
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL n, k; int main(){ while (~scanf("%lld%lld", &n, &k)){
printf("%lld\n", k * (n - k + 1));
} return 0;
}
Problem C
这道题的题意是爸爸和儿子玩游戏,爸爸想输,而且输给儿子的值一定要最小……
仰望了WKC的博客
还有这种操作……
不停地DFS下去,到达一定时间就退出并输出解。
也就是卡时。
我们先做一遍区间DP,求出区间[l, r]的两个信息:
一个是如果只考虑[l, r],爸爸的得分减去儿子的得分的最大值。
一个是如果只考虑[l, r],爸爸的得分减去儿子的得分的最小值。
哪怕是正的也没关系……
然后就是DFS,三个剪枝,卡时间。
两组数据,3s的时限,1500Ms一组,就过了。
(事实上0Ms就可以过……)
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL; const int N = 105; int mn[N][N], mx[N][N];
int a[N], n;
int ans;
double st; void init(){
memset(mn, 63, sizeof mn);
memset(mx, -63, sizeof mx); rep(i, 1, n + 1) mx[i][i - 1] = mn[i][i - 1] = 0; dec(l, n, 1){
rep(r, l, n){
int ll = l, rr = r, sub = 0;
if (a[ll] > a[rr]) sub = a[ll++];
else sub = a[rr--]; mx[l][r] = max(mx[l][r], a[ll] + mx[ll + 1][rr] - sub);
mn[l][r] = min(mn[l][r], a[ll] + mn[ll + 1][rr] - sub); mx[l][r] = max(mx[l][r], a[rr] + mx[ll][rr - 1] - sub);
mn[l][r] = min(mn[l][r], a[rr] + mn[ll][rr - 1] - sub);
}
}
} void dfs(int l, int r, int cnt){ if (clock() - st > 1400) return;
if (l > r){
ans = max(ans, cnt);
return;
} if (cnt + mn[l][r] >= 0) return;
if (cnt + mx[l][r] <= ans) return;
if (cnt + mx[l][r] < 0){
ans = max(ans, cnt + mx[l][r]);
return;
} int sub = 0;
if (a[l] >= a[r]) sub = a[l++];
else sub = a[r--]; dfs(l + 1, r, cnt + a[l] - sub);
dfs(l, r - 1, cnt + a[r] - sub);
} int main(){ while (~scanf("%d", &n)){
rep(i, 1, n) scanf("%d", a + i);
init(); st = clock(); ans = -(1 << 30);
dfs(1, n, 0); if (ans == -(1 << 30)) puts("The child will be unhappy...");
else printf("%d\n", -ans);
} return 0;
}
Problem D
对原序列求一遍最长不下降子序列,计长度为x
同时求一遍最长不上升子序列,计长度为y
则 $max(x, y) + k >= n$ 时符合题意。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL; const int N = 1e5 + 10;
int n, k;
int a[N], c[N], f[N];
int T, ans; void update(int x, int val){
for (; x <= 100001; x += x & -x) c[x] = max(c[x], val);
} int query(int x){
int ret = 0;
for (; x; x -= x & -x) ret = max(ret, c[x]);
return ret;
} int main(){ scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &k);
rep(i, 1, n) scanf("%d", a + i);
memset(c, 0, sizeof c);
memset(f, 0, sizeof f); rep(i, 1, n){
f[i] = query(a[i]) + 1;
update(a[i], f[i]);
} ans = 0 ;
rep(i, 1, n) ans = max(ans, f[i]);
memset(f, 0, sizeof f);
memset(c, 0, sizeof c);
dec(i, n, 1){
f[i] = query(a[i]) + 1;
update(a[i], f[i]);
} rep(i, 1, n) ans = max(ans, f[i]);
if (ans + k >= n) puts("A is a magic array.");
else puts("A is not a magic array.");
} return 0;
}
Problem E
$ans = F(2x + 3) - 1$
其中F()为斐波那契数列
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const LL mod = 998244353; struct Matrix{ LL arr[3][3];} mul, num, unit; LL k; Matrix Mul(Matrix a, Matrix b){
Matrix c;
rep(i, 1, 2) rep(j, 1, 2){
c.arr[i][j] = 0;
rep(k, 1, 2) (c.arr[i][j] += (a.arr[i][k] * b.arr[k][j] % mod)) %= mod;
}
return c;
} Matrix Pow(Matrix a, LL k){
Matrix ret(unit); for (; k; k >>= 1, a = Mul(a, a)) if (k & 1) ret = Mul(ret, a); return ret;
} int main(){ mul.arr[1][1] = 1; mul.arr[1][2] = 1;
mul.arr[2][1] = 1; mul.arr[2][2] = 0; rep(i, 1, 2) unit.arr[i][i] = 1;
num.arr[1][1] = 1;
num.arr[2][1] = 1; while (~scanf("%lld", &k)){
Matrix P = Pow(mul, 2 * k + 1);
Matrix c = Mul(P, num);
printf("%lld\n", (c.arr[1][1] + mod - 1) % mod);
} return 0;
}
Problem G
叉姐的套路果然强大
首先固定一棵生成树,每一条边的权值都是1
加边的过程相当于原来这棵树上这两个点之间的所有边权值变成0。
询问相当于在两点之间的路径上有多少1
很容易想到用树链剖分来实现。然而这题卡了树链剖分。
然后就学习了一下叉姐的套路。
用一个并查集维护某个点上面的离他最近的边权为1的边。
因为总共只有n - 1条边。所以最多只要操作n - 1次。操作的时候暴力往上合并。
计数的话用一个树状数组就可以了。
时间复杂度$O(nlogn)$
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL;
typedef pair <int, int> PII; const int N = 1e5 + 10; int s[N], son[N], deep[N], father[N], sz[N], top[N], l[N], r[N];
int q, tot, n;
int T;
int ti;
int m;
int f[N];
int ca = 0;
vector <int> v[N];
vector <PII> edge; int getfather(int x){
return f[x] == x ? x : f[x] = getfather(f[x]);
} void Merge(int x, int y){
int fx = getfather(x);
int fy = getfather(y);
if (fx == fy) return;
f[fx] = fy;
} void dfs1(int x, int fa, int dep){
l[x] = ++ti;
deep[x] = dep;
father[x] = fa;
son[x] = 0;
sz[x] = 1;
for (auto u : v[x]){
if (u == fa) continue;
dfs1(u, x, dep + 1);
sz[x] += sz[u];
if (sz[son[x]] < sz[u]) son[x] = u;
}
r[x] = ti;
} void dfs2(int x, int tp){
top[x] = tp;
if (son[x]) dfs2(son[x], tp);
for (auto u : v[x]){
if (u == father[x] || u == son[x]) continue;
dfs2(u, u);
}
} int c[N]; void add(int x, int val){
for (; x <= n; x += x & -x) c[x] += val;
} void update(int l, int r, int d){
add(l, d);
add(r + 1, -d);
} int query(int x){
int ret = 0;
for (; x; x -= x & -x) ret += c[x];
return ret;
} int LCA(int x, int y){
for (; top[x] ^ top[y]; ){
if (deep[top[x]] < deep[top[y]]) swap(x, y);
x = father[top[x]];
}
return deep[x] > deep[y] ? y : x;
} void work(int x, int y){
x = getfather(x);
y = getfather(y);
int z = getfather(LCA(x, y));
while (getfather(x) != getfather(z)){
update(l[getfather(x)], r[getfather(x)], 1);
Merge(getfather(x), father[getfather(x)]);
}
while (getfather(y) != getfather(z)){
update(l[getfather(y)], r[getfather(y)], 1);
Merge(getfather(y), father[getfather(y)]);
}
} int main(){ scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
rep(i, 0, n + 1) v[i].clear();
rep(i, 1, n) f[i] = i;
edge.clear(); rep(i, 1, m){
int x, y;
scanf("%d%d", &x, &y);
int fa = getfather(x);
int fb = getfather(y); if (fa != fb){
v[x].push_back(y);
v[y].push_back(x);
f[fa] = fb;
} else edge.push_back(MP(x, y));
} tot = 0; ti = 0;
dfs1(1, 0, 0);
dfs2(1, 1); memset(c, 0, sizeof c);
rep(i, 1, n) f[i] = i;
for (auto cnt : edge) work(cnt.fi, cnt.se); printf("Case #%d:\n", ++ca);
scanf("%d", &q);
while (q--){
int op;
scanf("%d", &op);
if (op == 1){
int x, y;
scanf("%d%d", &x, &y);
work(x, y);
} else{
int x, y;
scanf("%d%d", &x, &y);
int z = LCA(x, y);
printf("%d\n", deep[x] + deep[y] - deep[z] * 2 - (query(l[x]) + query(l[y]) - 2 * query(l[z])));
}
} } return 0;
}
Problem H
体现我低下的智商的一道题……
这题还是走了不少弯路(看来我对树型DP的理解还不深入)
我的方法是考虑两种情况。
第一种情况是从某个点买入然后在以他为根的子树中的某个结点卖出。
或者从某个点卖出然后在以他为根的子树中的某个结点买入。
设这个点为x,以他为根的子树中的某个结点为y。
则收益1 = $s[x] - s[y] + a[y] - a[x] = (s[x] - a[x]) - (s[y] - a[y])$
收益2 = $s[x] - s[y] + a[x] - a[y] = (s[x] + a[x]) - (s[y] + a[y])$
其中s[i]为根结点到i的路程长度。
对某个x,要使收益1最大,则$(s[y] - a[y])$要最小。
对某个x,要使收益2最大,则$(s[y] + a[y])$要最小。
那么我们预处理出每个点这两个值,建立ST表,
然后对每个点求出前序DFS序和后序DFS序,
区间查询最小值。
那么第一种情况就解决了。
第二种情况,枚举每个点,求LCA为这个点的两个点之间的最优解。
树型DP就可以了。
以上是我在比赛的时候的想法(真的太麻烦了)
Code如下(比赛的时候还没写完,赛后稍稍fix了下就过了)
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL;
typedef pair<int, int> PII; const int N = 1e5 + 10;
const int A = 19; int T, n;
int ti, ans;
int f[N][A], g[N][A], a[N], c[N], d[N], F[N], G[N], s[N], l[N], r[N], fl[N];
vector <PII> v[N]; void dfs(int x, int fa, int now){
s[x] = now;
l[x] = ++ti;
for (auto cnt : v[x]){
int u = cnt.fi, w = cnt.se;
if (u == fa) continue;
dfs(u, x, now + w);
}
r[x] = ti;
} void ST(){
rep(i, 1, n) f[i][0] = c[fl[i]];
rep(j, 1, 18) rep(i, 1, n) if ((i + (1 << j) - 1) <= n) f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
rep(i, 1, n) g[i][0] = d[fl[i]];
rep(j, 1, 18) rep(i, 1, n) if ((i + (1 << j) - 1) <= n) g[i][j] = min(g[i][j - 1], g[i + (1 << (j - 1))][j - 1]);
} inline int solve_f(int l, int r){
int k = (int)log2((double)(r - l + 1));
return min(f[l][k], f[r - (1 << k) + 1][k]);
} inline int solve_g(int l, int r){
int k = (int)log2((double)(r - l + 1));
return min(g[l][k], g[r - (1 << k) + 1][k]);
} void ask(int x){
ans = max(ans, c[x] - solve_f(l[x], r[x]));
ans = max(ans, d[x] - solve_g(l[x], r[x]));
} void dfs2(int x, int fa){
F[x] = c[x];
G[x] = d[x];
for (auto cnt : v[x]){
int u = cnt.fi;
if (u == fa) continue;
dfs2(u, x);
F[x] = min(F[x], F[u]);
G[x] = min(G[x], G[u]);
}
} void dp(int x, int fa){
int m1 = 1 << 30;
int m2 = 1 << 30;
int yy = 0;
for (auto cnt : v[x]){
int u = cnt.fi;
if (u == fa) continue;
if (yy){
ans = max(ans, 2 * s[x] - F[u] - m2);
ans = max(ans, 2 * s[x] - G[u] - m1);
} dp(u, x);
m1 = min(m1, F[u]);
m2 = min(m2, G[u]);
yy = 1; }
} int main(){ scanf("%d", &T);
while (T--){
scanf("%d", &n);
rep(i, 0, n + 1) v[i].clear();
rep(i, 1, n) scanf("%d", a + i);
rep(i, 2, n){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
v[x].push_back(MP(y, z));
v[y].push_back(MP(x, z));
} memset(s, 0, sizeof s);
memset(l, 0, sizeof l); ti = 0;
dfs(1, 0, 0); rep(i, 1, n) c[i] = s[i] + a[i];
rep(i, 1, n) d[i] = s[i] - a[i];
rep(i, 1, n) fl[l[i]] = i; ST();
ans = 0;
rep(i, 1, n) ask(i); memset(F, 0, sizeof F);
memset(G, 0, sizeof G); dfs2(1, 0);
dp(1, 0);
printf("%d\n", ans); }
return 0;
}
赛后想想,其实根本不需要ST表……
直接来个预处理,第一种情况就解决了
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL;
typedef pair<int, int> PII; const int N = 1e5 + 10;
const int A = 19; int T, n;
int ti, ans;
int f[N][A], g[N][A], a[N], c[N], d[N], F[N], G[N], s[N], l[N], r[N], fl[N];
vector <PII> v[N]; void dfs(int x, int fa, int now){
s[x] = now;
l[x] = ++ti;
for (auto cnt : v[x]){
int u = cnt.fi, w = cnt.se;
if (u == fa) continue;
dfs(u, x, now + w);
}
r[x] = ti;
} void ST(){
rep(i, 1, n) f[i][0] = c[fl[i]];
rep(j, 1, 18) rep(i, 1, n) if ((i + (1 << j) - 1) <= n) f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
rep(i, 1, n) g[i][0] = d[fl[i]];
rep(j, 1, 18) rep(i, 1, n) if ((i + (1 << j) - 1) <= n) g[i][j] = min(g[i][j - 1], g[i + (1 << (j - 1))][j - 1]);
} inline int solve_f(int l, int r){
int k = (int)log2((double)(r - l + 1));
return min(f[l][k], f[r - (1 << k) + 1][k]);
} inline int solve_g(int l, int r){
int k = (int)log2((double)(r - l + 1));
return min(g[l][k], g[r - (1 << k) + 1][k]);
} void ask(int x){
ans = max(ans, c[x] - solve_f(l[x], r[x]));
ans = max(ans, d[x] - solve_g(l[x], r[x]));
} void dfs2(int x, int fa){
F[x] = c[x];
G[x] = d[x];
for (auto cnt : v[x]){
int u = cnt.fi;
if (u == fa) continue;
dfs2(u, x);
F[x] = min(F[x], F[u]);
G[x] = min(G[x], G[u]);
}
} void dp(int x, int fa){
int m1 = 1 << 30;
int m2 = 1 << 30;
int yy = 0;
for (auto cnt : v[x]){
int u = cnt.fi;
if (u == fa) continue;
if (yy){
ans = max(ans, 2 * s[x] - F[u] - m2);
ans = max(ans, 2 * s[x] - G[u] - m1);
} dp(u, x);
m1 = min(m1, F[u]);
m2 = min(m2, G[u]);
yy = 1; }
} int main(){ scanf("%d", &T);
while (T--){
scanf("%d", &n);
rep(i, 0, n + 1) v[i].clear();
rep(i, 1, n) scanf("%d", a + i);
rep(i, 2, n){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
v[x].push_back(MP(y, z));
v[y].push_back(MP(x, z));
} memset(s, 0, sizeof s);
memset(l, 0, sizeof l); ti = 0;
dfs(1, 0, 0); rep(i, 1, n) c[i] = s[i] + a[i];
rep(i, 1, n) d[i] = s[i] - a[i];
rep(i, 1, n) fl[l[i]] = i; ST();
ans = 0;
rep(i, 1, n) ask(i); memset(F, 0, sizeof F);
memset(G, 0, sizeof G); dfs2(1, 0);
dp(1, 0);
printf("%d\n", ans); }
return 0;
}
Problem J
最后这题完全读不进去啊……
题目大意就是给出一棵树,和若干条路径。
由于某些点不可经过,这些给出的路径是走不通的。
也就是说如果他给出了路径(u, v),那么u就不能走到v,反过来也一样。
求不可经过的点最少有几个。
这道题要用到一个结论:
如果树上两条路径有交集,
假设u1和u2分别为两条路径两个端点的LCA,
一定存在u1属于这个交集,或者u2属于这个交集。
对于路径(u, v),我们求出u和v的LCA——z。
然后对这p条路径,我们以deep[z]为关键字排序。
deep[z]越大,排越前面。
接下来就是一个贪心的过程。
我们从前往后处理这些路径,
如果当前这条路径的u或v已经被标记,那么直接跳过。
如果当前这条路径的u或v都没有被标记,
那么我们标记以z为根的子树的所有点。
然后对答案加1.
之前我们预处理出所有点的前序DFS序l[i]和后序DFS序r[i],
若要标记以i为根的子树的所有点,那么给区间l[i]到r[i]打上标记即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 1e4 + 10;
const int A = 18; int deep[N], c[N], l[N], r[N], sz[N], son[N], top[N], father[N];
int n, m, ti, ans;
vector <int> v[N]; struct node{
int x, y, z;
friend bool operator < (const node &a, const node &b){
return deep[a.z] > deep[b.z];
}
} path[N * 5]; void dfs(int x, int fa, int dep){
father[x] = fa;
deep[x] = dep;
l[x] = ++ti;
sz[x] = 1; for (auto u : v[x]){
if (u == fa) continue;
dfs(u, x, dep + 1);
sz[x] += sz[u];
if (sz[son[x]] < sz[u]) son[x] = u;
} r[x] = ti;
} void dfs2(int x, int fa, int tp){
top[x] = tp;
if (son[x]) dfs2(son[x], x, tp); for (auto u : v[x]){
if (u == son[x] || u == fa) continue;
dfs2(u, x, u);
}
} int LCA(int x, int y){
for (; top[x] ^ top[y]; ){
if (deep[top[x]] < deep[top[y]]) swap(x, y);
x = father[top[x]];
} return deep[x] > deep[y] ? y : x;
} inline int update(int x, int y){
for (; x <= n; x += x & -x) ++c[x]; ++y;
for (; y <= n; y += y & -y) --c[y];
} inline int query(int x){
int ret = 0;
for (; x; x -= x & -x) ret += c[x];
return ret;
} int main(){ while (~scanf("%d", &n)){
++n;
rep(i, 0, n + 1) v[i].clear(); ti = 0;
rep(i, 2, n){
int x, y;
scanf("%d%d", &x, &y);
++x; ++y;
v[x].push_back(y);
v[y].push_back(x);
} memset(son, 0, sizeof son);
dfs(1, 0, 0);
dfs2(1, 0, 1); scanf("%d", &m);
rep(i, 1, m){
int x, y, z;
scanf("%d%d", &x, &y);
++x;
++y;
z = LCA(x, y);
path[i] = node{x, y, z};
} sort(path + 1, path + m + 1);
memset(c, 0, sizeof c); ans = 0;
rep(i, 1, m){
int x = query(l[path[i].x]), y = query(l[path[i].y]);
if (x || y) continue;
update(l[path[i].z], r[path[i].z]);
++ans;
} printf("%d\n", ans); } return 0;
}
Problem L
从第1个点扫过去,扫到第x1个点的时候游戏终止。
于是我们从x1+ 1接着扫,扫到游戏终止时的那个点x2
继续从x2 + 1开始扫。
周而复始,直到扫完为止。扫完一遍更新一次答案。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 1e6 + 10;
int n, l, r, ret, ans;
int a[N], b[N], c[N << 1], f[N << 1]; int main(){ while (~scanf("%d", &n)){
rep(i, 1, n) scanf("%d", a + i);
rep(i, 1, n) scanf("%d", b + i); rep(i, 1, n) c[i] = a[i] - b[i]; rep(i, 1, n) c[i + n] = c[i];
rep(i, 1, n << 1) f[i] = f[i - 1] + c[i];
l = 1; r = 1; c[1] = 0;
rep(i, 1, n) c[i] = c[i - 1] + a[i];
rep(i, 1, n) c[n + i] = c[n + i - 1] + a[i]; ret = 0;
while (true){
while (r < 2 * n && r - l + 1 < n && f[r] - f[l - 1] >= 0) ++r;
if (c[r] - c[l - 1] > ret){
ret = c[r] - c[l - 1];
ans = l - 1;
}
++r;
l = r;
if (l > 2 * n) break;
}
printf("%d\n", ans);
} return 0;
}
2017 ACM/ICPC Asia Regional Shenyang Online 记录的更多相关文章
- 2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- hdu6201 transaction transaction transaction(from 2017 ACM/ICPC Asia Regional Shenyang Online)
最开始一直想着最短路,不过看完题解后,才知道可以做成最长路.唉,还是太菜了. 先上图: 只要自己添加两个点,然后如此图般求最长路即可,emmm,用SPFA可以,迪杰斯特拉也可以,或者别的都ok,只要通 ...
- 2017 ACM/ICPC Asia Regional Shenyang Online 12 card card card
题目大意: 给出两个长度为n的序列A,B,从1开始依次加Ai,减Bi,分数为第一次为当前和为负数的位置以前的Ai之和(左闭右开区间).同时有一种操作可以把当前的A1,B1移动到序列最后,注意序列A的各 ...
- 2017 ACM/ICPC Asia Regional Shenyang Online(部分题解)
HDU 6197 array array array 题意 输入n和k,表示输入n个整数和可以擦除的次数k,如果至多擦除k次能是的数组中的序列是不上升或者是不下降序列,就是魔力数组,否则不是. 解题思 ...
- HDU 6205(尺取法)2017 ACM/ICPC Asia Regional Shenyang Online
题目链接 emmmm...思路是群里群巨聊天讲这题是用尺取法.....emmm然后就没难度了,不过时间上3000多,有点.....盗了个低配本的读入挂发现就降到2800左右, 翻了下,发现神犇Clar ...
- HDU 6198(2017 ACM/ICPC Asia Regional Shenyang Online)
思路:找规律发现这个数是斐波那契第2*k+3项-1,数据较大矩阵快速幂搞定. 快速幂入门第一题QAQ #include <stdio.h> #include <stdlib.h& ...
- 2017 ACM/ICPC Asia Regional Shenyang Online array array array
2017-09-15 21:05:41 writer:pprp 给出一个序列问能否去掉k的数之后使得整个序列不是递增也不是递减的 先求出LIS,然后倒序求出最长递减子序列长度,然后判断去k的数后长度是 ...
- 2017 ACM/ICPC Asia Regional Shenyang Online card card card
题意:看后面也应该知道是什么意思了 解法: 我们设置l,r,符合条件就是l=起始点,r=当前点,不符合l=i+1 学习了一下FASTIO #include <iostream> #incl ...
- 2017 ACM/ICPC Asia Regional Shenyang Online transaction transaction transaction
Problem Description Kelukin is a businessman. Every day, he travels around cities to do some busines ...
随机推荐
- UEditor中多图上传的bug
多图上传 预览:支持浏览器版本 IE8以上 在线管理:由于存在bug,显示不了 ueditor-1.1.1.jar解压后找到FileManager 1.修改com.baidu.ueditor.hun ...
- ios调试小结
Xcode底部的小黑盒是我们调试时的好朋友,它可以输出日志信息.错误信息以及其他有用的东西来帮你跟踪错误,除了可以看到日志直接输出的信息外,我们编程过程中也可以在某些断点停留,来检查app的多个方面. ...
- Clover KextsToPatch 使用方法 2015.10.21
Clover KextsToPatch 使用方法 2015.10.21 前些天,因为 Thinkpad X230 BIOS 白名单限制,给她换了一块 ar9285 无线网卡,只是因为这块网卡正好可 ...
- HDU-2018-奶牛的故事
这题找到递推式就好写了,递推式大致是: f=n (n<=4) f=f(n-1)+f(n-3) (n>4) 其实这题的题意,我觉得是有很大的问题的,它前后说的每年年初的意思都不一样,敬请参考 ...
- python 发送附件
#!/usr/bin/env python # encoding: utf-8 #@author: 东哥加油! #@file: sksendmail.py #@time: 2018/8/20 13:3 ...
- CSS3-弹性盒模型-FlexBox
Flex容器属性 display 定义一个Flex容器,根据其取的值来决定是内联还是块.Flex容器会为其内容建立新的伸缩格式化上下文. .container { display: flex; /* ...
- Web Best Practices
Web Best Practices General Google WebFundamentals - Github JavaScript Style Guide - Github Google In ...
- windows下的host工作原理
在Window系统中有个Hosts文件(没有后缀名),在Windows98系统下该文件在Windows目录,在Windows2000/XP系统中位于C:\Winnt\System32\Drivers\ ...
- 【Luogu】P1586四方定理(DP)
题目链接 此题使用DP.设f[i][j]表示数i用j个数表示,则对于所有的k<=sqrt(i),有 f[i][j]=∑f[i-k*k][j-1] 但是这样会有重复情况.所以先枚举k,再枚举i和j ...
- 【2018.10.18】noip模拟赛Day2 地球危机(2018年第九届蓝桥杯C/C++A组省赛 三体攻击)
题目描述 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 $A × B × C$ 艘战舰,在太 空中排成一个 $A$ 层 $B$ 行 $C$ 列的立方体.其中,第 $i$ 层第 $j$ 行第 $k ...