BUPT2017 wintertraining(16) #9
龟速补题。目前基本弃坑。已暂时放弃 D、I 两题。
下面不再写题意了直接说解法注意事项之类,直接放contest链接。
https://vjudge.net/contest/151537
A.The Perfect Stall
很明显的二分图匹配,可以跑最大流
我是直接写的匈牙利算法,hungary,不是hungry
(虽然读音差不多???
事实证明浪了一个寒假我连hungary算法都不会写了
#include <cstdio>
#include <vector>
#include <cstring> using namespace std; vector <int> e[];
int n, m, tim, ans, pre[], vis[]; int hungary(int u) {
vis[u] = tim;
for(int v, i = ;i < e[u].size();i ++) {
v = e[u][i];
if(vis[v] != tim) {
vis[v] = tim;
if(!pre[v] || hungary(pre[v]))
return pre[v] = u, ;
}
}
return ;
} int main() {
while(~scanf("%d %d", &n, &m)) {
ans = ;
memset(e, , sizeof e);
memset(pre, , sizeof pre);
memset(vis, , sizeof vis);
for(int u, v, i = ;i <= n;i ++) {
scanf("%d", &u);
for(int j = ;j <= u;j ++) {
scanf("%d", &v);
e[i].push_back(v + n);
}
}
for(tim = ;tim <= n;tim ++)
ans += hungary(tim);
printf("%d\n", ans);
}
return ;
}
B.Nim
Nim问题的拓展:
给定一种局面,询问当前局面下
你有多少种不同的保证必胜的操作方法
(又举例把自己难住所以去复习了一下)
显然只要使操作后石子堆异或和为0即可
题外话,之前没怎么注意过运算优先级
然而昨天才认识到AND优先级比OR高
还有位运算清楚不清楚优先级最好加括号
因为今天才知道XOR优先级比 <= 低
#include <cstdio> int n, k[]; int main() {
while(scanf("%d", &n), n != ) {
int ans = , num = ;
for(int i = ;i <= n;i ++)
scanf("%d", &k[i]), num ^= k[i];
for(int i = ;i <= n;i ++)
ans += ((num ^ k[i]) < k[i]);
printf("%d\n", ans);
}
return ;
}
C.sightseeing
一个最短路和次短路计数问题
// unidirectional单向!不要看见un就以为是什么否定前缀
// 就以为是无向边了好吗!naive,多学点英语不好吗
计数比较简单啦,开数组num[2][maxn]
dis[i]表示起点到 i 的最短距离
num[0][i]到 i 的距离为dis[i]的路径数
num[1][i]到 i 的距离为dis[i] + 1的路径数
初始化num[0][s] = 1 结果就是num[0][t] + num[1][t]
由于同时记录最短路和次短路所以如果用spfa会增加很多入队次数可能TLE?
不是很清楚但是我是用的spfa过的,别人题解几乎清一色的dijkstra?
在dr帮助下终于解决了自己的一个困惑
在计数用的spfa中需要同时记录节点和距离
距离数组ddis因为是会被更新的所以入队时需要记录下来距离!
当然我的写法偏非主流,参考价值有限
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring> using namespace std; struct node{int x, y, z;}; const int maxn = , inf = ; int Case, n, m; int dis[maxn], ddis[maxn], flag[maxn], vis[][maxn], num[][maxn]; vector <pair<int, int> > e[maxn]; queue <int> q; queue <node> qq; int main() {
scanf("%d", &Case);
while(Case -- ) {
memset(e, , sizeof e);
int u, v, w, s, t, p, dd, dp;
scanf("%d %d", &n ,&m);
for(int i = ;i <= m;i ++) {
scanf("%d %d %d", &u, &v, &w);
e[u].push_back(make_pair(v, w));
}
scanf("%d %d", &s, &t);
for(int i = ;i <= n;i ++)
dis[i] = ddis[i]= inf;
dis[s] = ddis[s] = , q.push(s);
while(!q.empty()) {
u = q.front(), flag[u] = , q.pop();
for(int i = ;i < e[u].size();i ++) {
v = e[u][i].first, w = e[u][i].second;
if(dis[u] + w < dis[v]) {
dis[v] = dis[u] + w;
if(v != t && !flag[v]) q.push(v), flag[v] = ;
}
}
}
num[][s] = ;
qq.push((node) {s, , });
while(!qq.empty()) {
u = qq.front().x, p = qq.front().y, dp = qq.front().z, vis[p][u] = , qq.pop();
for(int i = ;i < e[u].size();i ++) {
v = e[u][i].first, w = e[u][i].second;
if(dp + w <= ddis[v]) {
ddis[v] = dp + w;
if(ddis[v] == dis[v]) {
num[][v] += num[p][u];
if(v != t && !vis[][v]) vis[][v] = , qq.push((node) {v, , ddis[v]});
}
else if(ddis[v] == dis[v] + ) {
num[][v] += num[p][u];
if(v != t && !vis[][v]) vis[][v] = , qq.push((node) {v, , ddis[v]});
}
else if(v != t && !vis[][v]) vis[][v] = , qq.push((node) {v, , ddis[v]});
}
else if(dp + w == dis[v] + ) {
num[][v] += num[p][u];
if(v != t && !vis[][v]) vis[][v] = , qq.push((node) {v, , dp + w});
}
}
if(p < ) num[p][u] = ;
}
printf("%d\n", num[][t] + num[][t]);
num[][t] = num[][t] = ;
}
return ;
}
D.Let it bead
这个题完全是抄别人的代码啊
polya原理是什么啊,好吃吗
等我会了再把坑填上
#include <cstdio> long long f[]; int gcd(int x, int y) {
return y ? gcd(y, x % y) : x;
} int main() {
int c, s;
while(scanf("%d %d", &c, &s), c != ) {
f[] = ;
for(int i = ;i <= s;i ++)
f[i] = f[i - ] * c;
int sum = , cnt = ;
for(int i = ;i <= s;i ++)
sum += f[gcd(s, i)];
if(s & ) cnt = s * f[(s + ) >> ];
else cnt = (s >> ) * (f[(s >> ) + ] + f[s >> ]);
printf("%d\n", ((sum + cnt) >> ) / s);
}
return ;
}
E.going home
一个比较明显的最小费用最大流
s到H连边,流量1,费用0
m到t连边,流量1,费用0
h到m连边,流量1,费用为距离
直接抄的板子
#include <deque>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = , maxm = , inf = 0x3f3f3f3f; int dis(int x, int y) {
if(x < y) return y - x;
return x - y;
} struct point {
int x, y;
int operator - (const point & a) const {
return dis(x, a.x) + dis(y, a.y);
}
}a[maxn], b[maxn]; char mmp[maxn];
int n, m, s, t, c1, c2, d[maxn], v[maxn], pre[maxn], incf[maxn];
int len, ans, head[maxn], to[maxm], cap[maxm], cost[maxm], next[maxm], path[maxn]; void add(int x, int y, int v, int w) {
to[++ len] = y, cap[len] = v, next[len] = head[x], head[x] = len, cost[len] = w;
to[++ len] = x, cap[len] = , next[len] = head[y], head[y] = len, cost[len] = -w;
} bool spfa() {
deque <int> q;
q.push_back(s), incf[s] = inf;
memset(d, 0x3f, sizeof d), d[s] = ;
while(!q.empty()) {
int x = q.front();
q.pop_front(), v[x] = ;
for(int i = head[x];i;i = next[i]) {
if(cap[i] && d[to[i]] > d[x] + cost[i]) {
d[to[i]] = d[x] + cost[i];
pre[to[i]] = x, path[to[i]] = i;
incf[to[i]] = min(incf[x], cap[i]);
if(!v[to[i]]) {
v[to[i]] = ;
if(q.empty() || d[to[i]] < d[q.front()]) q.push_front(to[i]);
else q.push_back(to[i]);
}
}
}
}
if(d[t] == inf) return ;
for(int i = t;i != s;i = pre[i]) {
cap[path[i]] -= incf[t];
cap[path[i] ^ ] += incf[t];
}
return ans += incf[t] * d[t], ;
} int main() {
s = , t = ;
while(scanf("%d %d", &n, &m), n != ) {
len = , c1 = c2 = ans = ;
memset(head, , sizeof head);
for(int i = ;i <= n;i ++) {
scanf("%s", mmp + );
for(int j = ;j <= m;j ++)
if(mmp[j] == 'H') {
a[++ c1] = (point){i, j};
add(s, c1, , );
}
else if(mmp[j] == 'm') {
b[++ c2] = (point){i, j};
add( + c2, t, , );
}
}
for(int i = ;i <= c1;i ++)
for(int j = ;j <= c2;j ++)
add(i, j + , , a[i] - b[j]);
while(spfa());
printf("%d\n", ans);
}
return ;
}
F.Road to Cinema
之前做过的codeforces原题
简单地二分出能到达终点的最小容量
然后在所有容量满足条件的车里找最便宜的即可
#include <cstdio>
#include <algorithm> using namespace std; const int maxn = ; int n, k, s, t; int a[maxn], b[maxn], c[maxn]; bool judge(int x) {
long long sum = ;
for(int i = ;i < k;i ++) {
if(c[i] > x) return ;
if(c[i] * <= x) sum += c[i];
else sum += c[i] * -x;
}
return sum <= t;
} int main() {
int l = , r = , mid, ans = -;
scanf("%d %d %d %d", &n, &k, &s, &t);
for(int i = ;i <= n;i ++)
scanf("%d %d", &a[i], &b[i]), l = min(l, b[i]), r = max(r, b[i]);
for(int i = ;i <= k;i ++)
scanf("%d", &c[i]);
sort(c + , c + k + );
k ++, c[k] = s;
for(int i = ;i < k;i ++)
c[i] = c[i + ] - c[i];
while(l <= r){
mid = (l + r) >> ;
if(judge(mid)) r = mid - , ans = mid;
else l = mid + ;
}
if(ans == -) printf("-1");
else {
mid = ;
for(int i = ;i <= n;i ++)
if(b[i] >= ans)
mid = min(mid, a[i]);
printf("%d", mid);
}
return ;
}
G.play with chain
标题应该翻译成捆绑play?
一道很明显的splay
我能不抄板子打出来?不存在的!
我用指针写的双旋的
FLIP操作就像文艺平衡树一样
把操作区间左边相邻的点转到root
右边相邻的点转到root的右儿子
因为splay保持了原来的顺序
所以要操作的区间就是root的右儿子的左儿子那棵子树
打个翻转标记就完事了
CUT操作其实差不多,只是稍麻烦些
把操作区间左边相邻的点转到root
右边相邻的点转到root的右儿子
然后把要操作的区间拿下来
把剩下的树maintain完成后
把拿下来的区间再放到对应位置即可
#include <cstdio>
#include <algorithm> using namespace std; const int maxn = ; struct node {
bool rev;
int v, siz;
node *c[];
void pushdown();
node *init(int x); void update() {
siz = c[]->siz + c[]->siz + ;
} int cmp(int k) {
if(k <= c[]->siz) return ;
if(k == c[]->siz + ) return -;
return ;
}
}Null, spt[maxn]; int n, m, tot, cnt, out[maxn]; node *node::init(int x) {
v = x, rev = , siz = ;
c[] = c[] = &Null;
return this;
} void node::pushdown() {
if(!rev) return;
if(c[] != &Null) c[]->rev ^= ;
if(c[] != &Null) c[]->rev ^= ;
swap(c[], c[]), rev = ;
} node *build(int l, int r) {
if(l == r) return spt[++tot].init(r);
int mid = (l + r) >> ;
node *tmp = spt[++tot].init(mid);
if(l < mid) tmp->c[] = build(l, mid - );
if(r > mid) tmp->c[] = build(mid + ,r);
tmp->update();
return tmp;
} void print(node *&o) {
o->pushdown();
if(o->c[] != &Null) print(o->c[]);
out[cnt ++] = o->v;
if(o->c[] != &Null) print(o->c[]);
} void rot(node *&o, int k) {
o->pushdown();
node *tmp = o->c[k];
tmp->pushdown();
o->c[k] = tmp->c[!k];
tmp->c[!k]->pushdown();
tmp->c[!k] = o, o->update();
tmp->update(), o = tmp;
} void splay(node *&o, int k) {
o->pushdown();
int k1 = o->cmp(k);
if(k1 == -) return;
o->c[k1]->pushdown();
if(k1) k -= o->c[]->siz + ;
int k2 = o->c[k1]->cmp(k);
if(~k2) {
if(k2) k -= o->c[k1]->c[]->siz + ;
splay(o->c[k1]->c[k2], k);
if(k2 == k1) rot(o, k1);
else rot(o->c[k1], k2);
}
rot(o, k1);
} int main() {
int a, b, c, len;
char str[];
while(scanf("%d %d", &n, &m), n != -) {
tot = , cnt = ;
node *root = build(, n + ), *tmp;
while(m --) {
scanf("%s %d %d", str, &a, &b);
a ++, b ++, len = b - a + ;
if(str[] == 'C') {
scanf("%d", &c);
splay(root, a - );
splay(root->c[], len + );
tmp = root->c[]->c[];
root->c[]->c[] = &Null;
root->c[]->update();
root->update();
splay(root, c + );
splay(root->c[], );
root->c[]->c[] = tmp;
root->c[]->update();
root->update();
}
else {
splay(root, a - );
splay(root->c[], len + );
root->c[]->c[]->rev ^= ;
}
}
print(root);
for(int i = ;i < n;i ++)
printf("%d ", out[i]);
printf("%d\n", out[n]);
}
return ;
}
H.animals and puzzle
一看是cf的d题就来做了,结果是div1...
好的这个题我当然是看别人题解做的
首先我们很容易求dp[i][j]表示以(i,j)为右下角的最大正方形边长
然后就用到一个神奇的二分,二分里再套一个RMQ就解决了
这个二分是这样的
对于一个单独的查询,我们二分这个查询的答案为mid
然后再在以(x1 + mid - 1, y1 + mid - 1)为左上角
以(x2, y2)为右下角的正方形区域内求dp数组最大值k
如果k >= mid ,那么显然ans >= mid,即mid合法,l = mid +1
否则显然ans < mid,即mid不合法,r = mid -1
更正!效率为O((n^2+q)logn^2)
这里的RMQ为方便起见显然推荐倍增
(我一个一维RMQ宁愿线段树,LCA宁愿树剖的人都含泪推荐倍增了
#include <cstdio>
#include <algorithm> using namespace std; const int maxn = ; int n, m, t, x1, y1, x2, y2; int a[maxn][maxn], f[maxn][maxn][][]; int getmax() {
int p = , q = , l1 = , l2 = , tmp1, tmp2;
while(l1 <= x2 - x1 + ) l1 <<= , p ++;
p --, l1 >>= ;
while(l2 <= y2 - y1 + ) l2 <<= , q ++;
q -- ,l2 >>= ;
tmp1 = max(f[x1 + l1 - ][y1 + l2 - ][p][q], f[x2][y1 + l2 - ][p][q]);
tmp2 = max(f[x1 + l1 - ][y2][p][q], f[x2][y2][p][q]);
return max(tmp1, tmp2);
} bool judge(int r) {
x1 += r - , y1 += r - ;
bool ret = getmax() >= r;
x1 -= r - , y1 -= r - ;
return ret;
} int main() {
scanf("%d %d", &n, &m);
for(int i = ;i <= n;i ++) {
for(int j = ;j <= m;j ++) {
scanf("%d", &a[i][j]);
if(a[i][j]) f[i][j][][] = min(f[i - ][j - ][][], min(f[i - ][j][][], f[i][j - ][][])) + ;
else f[i][j][][] = ;
}
} for(int p = , l1 = ;l1 <= n;l1 <<= , p ++)
for(int q = , l2 = ;l2 <= m;l2 <<= , q ++) {
if(p + q == ) continue;
for(int i = l1;i <= n;i ++) {
for(int j = l2;j <= m;j ++) {
if(p != ) f[i][j][p][q] = max(f[i][j][p - ][q], f[i - (l1 >> )][j][p - ][q]);
else f[i][j][p][q] = max(f[i][j][p][q - ], f[i][j - (l2 >> )][p][q - ]);
}
}
} scanf("%d", &t);
for(int l, r, mid;t --;) {
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
l = , r = min(x2 - x1 + , y2 - y1 + );
while(l <= r) {
mid = (l + r) >> ;
if(judge(mid)) l = mid + ;
else r = mid - ;
}
printf("%d\n", r);
}
return ;
}
I.bear and bowling 4
f[i]代表以 i 为结尾的最大收益
有点奇妙的斜率DP
暂时放弃
J.runaway to a shadow
题意清晰,思路简单。
友情提示:这题不卡精度,只要你开的double不是float
不需要什么各种计算几何算法
只需要高中数学知识和cmath函数的计算几何模拟题
因为自己脑残所以写狗了3次
x,y写错。自己分类讨论好的情况忘写一种。pi 初始成3.141415926535。
#include <cmath>
#include <cstdio>
#include <algorithm> using namespace std; const int maxn = ; typedef long long ll; int n, m; double x0, Y0, v, t, R; double x[maxn], y[maxn], r[maxn]; double sqr(double x) {
return x * x;
} struct line {
double x, y;
bool operator < (const line &a) const {
if(x != a.x) return x < a.x;
return y < a.y;
}
}a[maxn]; int main() {
double pos, tmp, L, RR = 1.0, pi = 3.14159265358, ans = 0.0;
scanf("%lf %lf %lf %lf %d", &x0, &Y0, &v, &t, &n), R = v * t;
for(int i = ;i <= n;i ++) {
scanf("%lf %lf %lf", &x[i], &y[i], &r[i]);
if(sqr(x[i] - x0) + sqr(y[i] - Y0) <= sqr(r[i])) {
puts("1.00000000000");
return ;
}
if(sqrt(sqr(x[i] - x0) + sqr(y[i] - Y0)) >= R + r[i]) continue;
pos = atan2((y[i] - Y0), (x[i] - x0)) + pi;
if(sqr(R) + sqr(r[i]) >= sqr(x[i] - x0) + sqr(y[i] - Y0)) tmp = asin(r[i] / sqrt(sqr(x[i] - x0) + sqr(y[i] - Y0)));
else tmp = acos((sqr(R) - sqr(r[i]) + sqr(x[i] - x0) + sqr(y[i] - Y0)) / (sqrt(sqr(x[i] - x0) + sqr(y[i] - Y0)) * 2.0 * R));
m ++, a[m].y = pos + tmp ,a[m].x = pos - tmp;
if(a[m].x < 0.0) a[m + ].x = a[m].x + pi * 2.0, a[m].x = , a[++ m].y = pi * 2.0;
else if(a[m].y > pi * ) a[m + ].y = a[m].y - pi * , a[m].y = pi * , a[++ m].x = ;
}
sort(a + , a + m + );
L = a[].x, RR = a[].y;
for(int i = ;i <= m;i ++) {
if(a[i].x >= RR) ans += RR - L, L = a[i].x, RR = a[i].y;
else RR = max(RR, a[i].y);
}
ans += RR - L;
printf("%lf", abs(ans / (pi * )));
return ;
}
K.sightseeing
貌似高中做过的一个01规划问题
所以很显然的想到二分,然后处理边,判负环
好吧认真的说。显然最后结果必然是一个简单的环(自己思考
然后假设最优路径上fun之和为sf,路径长度为sl
则最优解 ans = sf / sl
那么我们二分一个mid,并把所有边的边长都设为 原长 * mid - fun[to]
若能找到负环,则存在sl * mid - sf <= 0
即mid <= sf / sl ,即 ans >= mid
所以二分就解释清楚了
至于判负环,dfs的spfa效率我不清楚
我用的bfs的spfa判负环,进队次数 >= n 即有负环
注意像我那么写的话,每次spfa开始要同时开始清理上次残留的队列以及visit数组!
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring> using namespace std; const int maxn = ;
const double eps = 1e-; int n, m, c[maxn], f[maxn], vis[maxn]; double d[maxn]; queue <int> q; vector <double> E[maxn];
vector <pair<int, double> > e[maxn]; bool spfa() {
while(!q.empty()) vis[q.front()] = , q.pop();
static int u, v;
static double w;
for(int i = ;i <= n;i ++)
c[i] = , d[i] = ;
q.push(), c[] = ;
while(!q.empty()) {
u = q.front();
q.pop(), vis[u] = , c[u] ++;
if(c[u] == n) return ;
for(int i = ;i < e[u].size();i ++) {
w = e[u][i].second, v = e[u][i].first;
if(d[u] + w <= d[v]) {
d[v] = d[u] + w;
if(!vis[v]) vis[v] = , q.push(v);
}
}
}
return ;
} bool judge(double x) {
for(int i = ;i <= n;i ++)
for(int j = ;j < e[i].size();j ++)
e[i][j].second = x * E[i][j] - 1.0 * f[e[i][j].first];
return spfa();
} int main() {
int u, v, w;
scanf("%d %d", &n, &m);
for(int i = ;i <= n;i ++)
scanf("%d", &f[i]);
for(int i = ;i <= m;i ++) {
scanf("%d %d %d", &u, &v, &w);
e[u].push_back(make_pair(v, w));
E[u].push_back(w);
}
double l = 0.0, r = 1000.0, mid, ans = 0.0;
while(l + eps <= r) {
mid = (l + r) / 2.0;
if(judge(mid)) l = mid + eps, ans = mid;
else r = mid - eps;
}
printf("%.2f", ans);
return ;
}
L.ZS and The Birthday Paradox
好吧这个题我也是看题解做出来的
其实最原始的公式很好推
然后我们需要对结果x/y约分后
分子分母再对mod=1e6+3取模
利用乘法逆元可知若有gcd(x,y)=z
我们求得z对mod的逆元
就可以直接x,y对mod取模
再分别乘以z对mod的逆元,再对mod取模即可
根据原始公式有y = 2^(nk)
x = (2^n)(2^n - 1)(2^n - 2)...(2^n - k + 1)
虽然x有k项,但是我们只需要求x % mod
x中的k项又是连续的,所以当 k >= mod时
一定会有x % mod = 0
k < mod时,直接暴力求x % mod 就行
到这里我们只需要考虑怎么求z了
显然z必然是2^i
求i的话,就是求(2^n - 1)(2^n - 2)...(2^n - k + 1)总共含多少个2
其实就是求(k - 1)! 中有多少个2
这里就能求i了
至此基本解决,再不懂看代码
#include <cstdio> typedef long long ll; const ll _mod = ; ll qow(ll x, ll k) {
static ll y;
x %= _mod, y = ;
for(;k > ;k >>= , x = x * x % _mod)
if(k & ) y = x * y % _mod;
return y;
} int main() {
ll n, k, fz, fm, tmp1, tmp2, tmp3;
scanf("%I64d %I64d", &n, &k);
if(n <= && (1ll << n) < k) {
puts("1 1");
return ;
}
fz = , tmp1 = qow(, n);
for(ll i = ;i < k;i ++) {
fz = fz * (tmp1 - i) % _mod;
if(!fz) break;
}
fm = qow(tmp1, k), tmp2 = n, k --;
while(k) k >>= , tmp2 += k;
tmp3 = qow(, tmp2), tmp3 = qow(tmp3, _mod - );
fz = fz * tmp3 % _mod;
fm = fm * tmp3 % _mod;
fz = (fm - fz) % _mod;
if(fz < ) fz += _mod;
printf("%I64d %I64d\n", fz, fm);
return ;
}
M.Vasiliy's Multiset
codeforces做过的原题
简单的二进制数的trie树
我写的指针+递归的确丑的没话说
注意!set里始终有0这个元素
所以要一开始手动插入0这个元素
尤其用指针不注意的话直接RE
#include <cstdio> struct node {
int num;
node *c[];
node() {
num = ;
c[] = c[] =NULL;
}
}; void insert(node *&o, int x, int k) {
if(o == NULL) o = new node;
o->num ++;
if(k == -) return;
insert(o->c[(x & ( << k)) != ], x, k - );
} void erase(node *&o, int x, int k) {
o->num --;
if(k == -) return;
erase(o->c[(x & ( << k)) != ], x, k - );
} void ask(node *&o, int x, int k, int ans) {
if(k == -) {
printf("%d\n", ans);
return;
}
int d = !(x & ( << k));
if(o->c[d] != NULL && o->c[d]->num != ) ask(o->c[d], x, k - , ans | ( << k));
else ask(o->c[!d], x, k - , ans);
} int main() {
int n, m;
char str[];
node *root = NULL;
insert(root, , );
scanf("%d", &n);
while(n --) {
scanf("%s %d", str, &m);
switch(str[]) {
case '+':insert(root, m, );break;
case '-':erase(root, m, );break;
case '?':ask(root, m, , );break;
}
}
return ;
}
BUPT2017 wintertraining(16) #9的更多相关文章
- BUPT2017 wintertraining(15) #3 题解
我觉得好多套路我都不会ヘ(;´Д`ヘ) 题解拖到情人节后一天才完成,还有三场没补完,真想打死自己.( ˙-˙ ) A - 温泉旅店 UESTC - 878 题意 有n张牌,两人都可以从中拿出任意 ...
- BUPT2017 wintertraining(15) #2 题解
这场有点难,QAQ.补了好久(。• ︿•̀。) ,总算能写题解了(つд⊂) A. Beautiful numbers CodeForces - 55D 题意 求\([l,r](1\le l_i\l ...
- BUPT2017 wintertraining(15) #1 题解
拖了一周才完成的题解,抛出一个可爱的表情 (っ'-')╮ =͟͟͞͞❤️.对我来说E.F比较难,都是线段树的题,有点久没写了. A - Infinite Sequence CodeForces - 6 ...
- BUPT2017 springtraining(16) #1 题解
https://vjudge.net/contest/162590 A: 不难发现,当L=R时输出L,当L<R时输出2. B: 贪心得配对.1和n配 2和n-1配,对与对直接只要花1个代价就可以 ...
- BUPT2017 wintertraining(15) #9
下面不再说明题意了请自行读题,直接放contest链接. https://vjudge.net/contest/151607 A.考虑当火车隔k站一停时 区间长度 >= k 的纪念品一定能买到 ...
- BUPT2017 springtraining(16) #6 ——图论
题目链接 A.容易发现最后字符的对应都是一对一的 或者说我们没办法出现最后多对一或者一对多的情况 所以只要算出 ‘a’ - 'z' 每个字符最后对应的字符即可 #include <cstdio& ...
- BUPT2017 springtraining(16) #4 ——基础数论
题目在这里 A.手动打表找规律得组合数 n -= 2, m -= 2, ans = C(n, m) #include <bits/stdc++.h> using namespace std ...
- BUPT2017 springtraining(16) #3 ——搜索与动态规划
题目在这里啊 A.最长上升子序列,范围很小所以写了简单的O(n^2)算法 #include <iostream> #define rep(i, j, k) for(int i = j;i ...
- BUPT2017 springtraining(16) #2 ——基础数据结构
题目在这里 A.似乎是个并查集+??? B.10W的范围,似乎可以暴力来一发二分+sort? 但我猜正解可以O(nlogn)? C.单调队列入门题目 #include <cstdio> ] ...
随机推荐
- GoLang笔记-数组和切片,本质是就是长度不可变的可变的区别
数组 Arrays 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值.在初始化后长度是固定的,无法修改其长度.当作为方法的入参传入时将复制一份数 ...
- 67.员工职位变动js
1.员工职位jsp <%@ page language="java" import="java.util.*" pageEncoding="UT ...
- Finding Nemo(搜索)
http://poj.org/problem?id=2049 题意:有一个迷宫,迷宫中有墙.门和空地.有M道墙,每一道墙用(x,y,d,t)表示,(x,y)表示墙的起始坐标,(d=1,t)表示向上t个 ...
- 如何判断js的变量的数据类型
文章首发: http://www.cnblogs.com/sprying/p/4349426.html 本文罗列了一般的Js中类型检测的方法,实际上是每个新手在构建Js知识体系时,都要知晓的,而我只是 ...
- 基于行为树的AI 与 Behavior Designer插件
优点: 0.行为逻辑和状态数据分离,任何节点都可以反复利用. 1.高度模块化状态,去掉状态中的跳转逻辑,使得状态变成一个"行为". 2."行为" ...
- codevs3304水果姐逛街(线段数)
3304 水果姐逛水果街Ⅰ 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 水果姐今天心情不错,来到了水果街. 水果 ...
- PHP电影小爬虫(2)
学习了别人的爬虫后自己改的一个,算是又回顾了一下php的使用 我们来利用simple_html_dom的采集数据实例,这是一个PHP的库,上手很容易.simple_html_dom 可以很好的帮助我们 ...
- android 蓝牙 通信 bluetooth
此例子基于 android demo Android的蓝牙开发,虽然不多用,但有时还是会用到, Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试需要两部手机: ...
- js常用操作~~~~将持续更新
1.替换多个模板变量 var s="my javascript is very poor,who can help me?" var reg=/(\w*)my(.*)is(.*)c ...
- MyBatis 配置控制台上显示sql语句(log4j.properties 之三)
### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.app ...