A. Hard to prepare

题意:有n个客人做成一圈,有$2^k$种面具,对于每种面具有一种面具不能使相邻的两个人戴,共有多少种做法。

思路: 把题意转化成相邻的人不能带同种面具。总数为$(2^k)^n$,减去一对相邻的客人戴同种面具$(2^k)^{(n-1)}*C(n,1)$,其中重复了两对相邻的客人戴同种面具$(2^k)^{(n-2)}*C(n,2)$,依次容斥。

最后所有人都戴同种面具的情况额外考虑,当n是奇数时,n-1对客人相同即所有人相同。n为偶数时,n-1对客人相同时用公式有重复的一轮,所以要加上。

设t=2^k

$\sum_{i = 0}^{i = n - 1} C_n^i \cdot t^{n - 1} * (-1)^i$ (n 是奇数)

$\sum_{i = 0}^{i = n - 1} C_n^i \cdot t^{n - 1} * (-1)^i + t$ (n 是偶数)

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 1000010 const ll MOD = (ll)1e9 + ; int t, n, k;
ll inv[N];
ll Bit[N];
ll Bitt[N]; inline void Init()
{
inv[] = ;
for (int i = ; i < N; ++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
Bit[] = ;
for (int i = ; i < N; ++i) Bit[i] = (Bit[i - ] * ) % MOD;
} inline void init()
{
Bitt[] = ; ll tmp = Bit[k];
for (int i = ; i <= n; ++i) Bitt[i] = (Bitt[i - ] * tmp) % MOD;
} inline void Run()
{
scanf("%d", &t); Init();
while (t--)
{
scanf("%d%d", &n, &k);
if (k == )
{
puts("");
continue;
}
else if (n == )
{
printf("%lld\n",Bit[k]);
continue;
}
init();
ll res = ;
ll C = ;
for (int i = ; i < n; ++i)
{
res = (res + (C * Bitt[n - i] % MOD * ((i & ) ? - : ) + MOD) % MOD) % MOD;
C = C * (n - i) % MOD * inv[i + ] % MOD;
}
res = (res + (Bit[k] * ((n & ) ? : )) % MOD + MOD) % MOD;
printf("%lld\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

B. BE, GE or NE

题意:每一轮有三种操作, 加上a 减去b 或者 取负 当且仅当 a, b, c 不为0时,对应的操作有效,给出一个上界和一个下界 大于等于上界就是 Good Ending 小于等于下界 就是 Bad Ending 否则就是 Normal Ending  两个人轮流操作,第一个人想要Good Ending 第二个人想要 Bad Ending  两个人操作最优,求最后的结局

思路:dp[i][j] 表示 第几轮 数字是多少的时候 ,记忆化爆搜 因为数字在$[-100, 100]$

 #include <bits/stdc++.h>

 using namespace std;

 typedef long long ll;

 const int MOD = (int)1e9 + ;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int maxn = (int)1e3 + ; struct node {
int a, b, c;
inline node() {}
inline node(int a, int b, int c) :a(a), b(b), c(c) {}
}arr[maxn]; int n, m, l, k;
int type[maxn][maxn];//1 good 0 normal -1 bad
int vis[maxn][maxn]; inline void Init()
{
memset(vis, , sizeof vis);
memset(type, , sizeof type);
} inline int DFS(int idx, int state)
{
if (idx > n)
{
if (state <= l) return -;
else if (state >= k) return ;
else return ;
}
if (vis[idx][state]) return type[idx][state];
vis[idx][state] = ;
int res = ;
//a
int A = , B = , C = ;
if (arr[idx].a)
{
A = DFS(idx + , min(, state + arr[idx].a));
}
//b
if (arr[idx].b)
{
B = DFS(idx + , max(-, state - arr[idx].b));
}
//c
if (arr[idx].c)
{
C = DFS(idx + , max(-, min(, state * -arr[idx].c)));
}
if ((A == || A == )&& (B == || B == ) && (C == || C == ) && (idx & ) == )
{
type[idx][state] = ;
return ;
}
else if ((A == - || A == ) && (B == - || B == ) && (C == - || C == ) && (idx & ) == )
{
type[idx][state] = -;
return -;
}
else if ((A == || B == || C == ) && (idx & ) == )
{
type[idx][state] = ;
return ;
}
else if ((A == - || B == - || C == -) && (idx & ) == )
{
type[idx][state] = -;
return -;
}
else
{
type[idx][state] = ;
return ;
}
} inline void RUN()
{
while (~scanf("%d %d %d %d", &n, &m, &k, &l))
{
Init();
for (int i = ; i <= n; ++i)
{
scanf("%d %d %d", &arr[i].a, &arr[i].b, &arr[i].c);
}
int ans = DFS(, m);
if (ans == )
{
puts("Good Ending");
}
else if (ans == -)
{
puts("Bad Ending");
}
else
{
puts("Normal Ending");
}
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE
}

C. Cacti Lottery

留坑。

D. Easy Math

留坑。

E. End Fantasy VIX

留坑。

F. Features Track

水。

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long typedef pair <ll, ll> pii; int t, n, tot;
ll ans, x, y;
map <pii, pii> mp; inline void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n); mp.clear(); ans = ;
for (int i = ; i <= n; ++i)
{
scanf("%d", &tot);
for (int j = ; j <= tot; ++j)
{
scanf("%lld%lld", &x, &y);
if (mp[pii(x, y)].second == i - ) ++mp[pii(x, y)].first;
else if (mp[pii(x, y)].second == i) continue;
else mp[pii(x, y)].first = ;
ans = max(ans, mp[pii(x, y)].first);
mp[pii(x, y)].second = i;
}
}
printf("%lld\n", ans);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

G. Trace

题意:每次给出一个点,然后就会形成两条线,如果后面的矩形覆盖了前面的边,那么这条边就消失了, 最后求剩下的边是多少

思路:分别处理x轴,y轴,然后排序,然后扫过去,每次加上自己的边长以及减去标号比自己小的并且长度比自己高的个数乘自己的边长

 #include <bits/stdc++.h>
using namespace std; #define N 50010
#define ll long long int n; struct node
{
int l, r;
int lazy, sum;
inline node() {}
inline node(int _l, int _r)
{
l = _l, r = _r;
lazy = -;
sum = ;
}
}tree[N << ]; inline void pushup(int id)
{
tree[id].sum = tree[id << ].sum + tree[id << | ].sum;
} inline void pushdown(int id)
{
if (tree[id].l >= tree[id].r) return;
if (~tree[id].lazy)
{
int lazy = tree[id].lazy; tree[id].lazy = -;
tree[id << ].lazy = tree[id << | ].lazy = lazy;
tree[id << ].sum = tree[id << | ].sum = ;
}
} inline void build(int id, int l, int r)
{
tree[id] = node(l, r);
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
} inline void update(int id, int l, int r, int val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].sum = val;
tree[id].lazy = val;
return;
}
pushdown(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) update(id << , l, r, val);
if (r > mid) update(id << | , l, r, val);
pushup(id);
} inline int query(int id, int l, int r)
{
if (tree[id].l >= l && tree[id].r <= r) return tree[id].sum;
pushdown(id);
int mid = (tree[id].l + tree[id].r) >> ;
int res = ;
if (l <= mid) res += query(id << , l, r);
if (r > mid) res += query(id << | , l, r);
return res;
} struct DT
{
int pos;
ll x, y;
inline void scan(int _pos)
{
pos = _pos;
scanf("%lld%lld", &x, &y);
}
}arr[N]; inline bool cmp1(DT a, DT b)
{
return a.x < b.x;
} inline bool cmp2(DT a, DT b)
{
return a.y < b.y;
} inline void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) arr[i].scan(i);
build(, , n);
sort(arr + , arr + + n, cmp1);
ll res = ;
for (int i = ; i <= n; ++i)
{
res += arr[i].y;
int pos = query(, , arr[i].pos);
res -= arr[i].y * pos;
update(, , arr[i].pos, );
update(, arr[i].pos, arr[i].pos, );
}
sort(arr + , arr + + n, cmp2);
update(, , n, );
for (int i = ; i <= n; ++i)
{
res += arr[i].x;
int pos = query(, , arr[i].pos);
res -= arr[i].x * pos;
update(, , arr[i].pos, );
update(, arr[i].pos, arr[i].pos, );
}
printf("%lld\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

栈维护:

 #include <bits/stdc++.h>
using namespace std; #define N 50010
#define ll long long int n; struct node
{
int pos;
ll x, y;
inline void scan(int _pos)
{
pos = _pos;
scanf("%lld%lld", &x, &y);
}
}arr[N]; inline bool cmp1(node a, node b)
{
return a.x < b.x;
} inline bool cmp2(node a, node b)
{
return a.y < b.y;
} inline void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) arr[i].scan(i);
sort(arr + , arr + + n, cmp1);
ll res = ;
stack<int>s;
for (int i = ; i <= n; ++i)
{
res += arr[i].y;
int cnt = ;
while (!s.empty() && s.top() < arr[i].pos)
{
cnt++;
s.pop();
}
res -= cnt * arr[i].y;
s.push(arr[i].pos);
}
while (!s.empty())
{
s.pop();
}
sort(arr + , arr + + n, cmp2);
for (int i = ; i <= n; ++i)
{
res += arr[i].x;
int cnt = ;
while (!s.empty() && s.top() < arr[i].pos)
{
cnt++;
s.pop();
}
res -= cnt * arr[i].x;
s.push(arr[i].pos);
}
printf("%lld\n", res);
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif Run();
return ;
}

H. Ryuji doesn't want to study

题意:两个操作,第一种是查询$[L, R]$ 区间内 $a[L] * len + a[L + 1] * (len - 1) + ... + a[R] * 1$

第二种是改变一个数

思路:线段树,记录两个值,一个是sum,另一个是 $a[L] * len + a[L + 1] * (len - 1) + ... + a[R] * 1$

考虑合并的时候 显然两个区间合并,相当于左区间的长度增加了右区间的长度,那么只需要多加上左区间的sum * 右区间长度

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long int n, q;
ll arr[N]; struct node
{
int l, r;
ll sum1, sum2;
inline node() {}
inline node(int l, int r, ll sum1, ll sum2) : l(l), r(r), sum1(sum1), sum2(sum2) {}
}tree[N << ]; inline void pushup(int id)
{
tree[id].sum1 = tree[id << ].sum1 + tree[id << | ].sum1;
tree[id].sum2 = tree[id << | ].sum2 + tree[id << ].sum2 + tree[id << ].sum1 * (tree[id << | ].r - tree[id << | ].l + );
} inline void build(int id, int l, int r)
{
tree[id] = node(l, r, , );
if (l == r)
{
tree[id].sum1 = arr[tree[id].l];
tree[id].sum2 = arr[tree[id].l];
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
pushup(id);
} inline void update(int id, int pos, ll val)
{
if (tree[id].l == tree[id].r)
{
tree[id].sum1 = val;
tree[id].sum2 = val;
return;
}
int mid = (tree[id].l + tree[id].r) >> ;
if (pos <= mid) update(id << , pos, val);
else update(id << | , pos, val);
pushup(id);
} ll anssum; inline void query(int id, int l, int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
anssum += tree[id].sum2 + tree[id].sum1 * (r - tree[id].r);
return;
}
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) query(id << , l, r);
if (r > mid) query(id << | , l, r);
} inline void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%lld", arr + i);
build(, , n);
int op, a, b; ll v;
for (int i = ; i <= q; ++i)
{
scanf("%d", &op);
if (op == )
{
scanf("%d%d", &a, &b);
anssum = ; query(, a, b);
printf("%lld\n", anssum);
}
else
{
scanf("%d%lld", &a, &v);
update(, a, v);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

I. Characters with Hash

水。

 #include <bits/stdc++.h>

 using namespace std;

 typedef long long ll;

 const int MOD = (int)1e9 + ;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int maxn = (int)1e6 + ; int n;
char s[];
char str[maxn]; int arr[maxn]; inline void RUN()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
scanf("%s", s);
scanf("%s", str);
int len = strlen(str);
for (int i = ; i < len; ++i)
{
arr[i] = abs(str[i] - s[]);
}
int ans = * len;
for (int i = ; i < len; ++i)
{
if (arr[i] == )
{
ans -= ;
}
else if (arr[i] < )
{
ans -= ;
break;
}
else
{
break;
}
}
if (ans == ) ans = ;
printf("%d\n", ans);
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE
}

J. Maze Designer
题意:有一个$n * m$ 的迷宫,我们要建一些边使得其构成迷宫,要花费最小,然后给出两个点求最短距离

思路:花费最小,其实就是求最大生成树,那么剩下的边则为迷宫

 #include <bits/stdc++.h>
using namespace std; #define N 300010
#define ll long long struct Edge
{
int to, nx; ll w;
inline Edge() {}
inline Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
inline bool operator < (const Edge &r) const
{
return w > r.w;
}
}edge[N << ], ed[N << ]; int n, m, q;
int head[N], pos, cnt, tot;
int pre[N], F[N << ], P[N], rmq[N << ];
ll dist[N]; inline void Init()
{
memset(head, -, sizeof head); pos = ; cnt = ; dist[] = ; tot = ;
for (int i = ; i <= n * m; ++i) pre[i] = i;
} inline void addedge(int u, int v, ll w)
{
edge[++pos] = Edge(v, head[u], w); head[u] = pos;
} struct ST
{
int mm[N << ];
int dp[N << ][];
inline void init(int n)
{
mm[] = -;
for (int i = ; i <= n; ++i)
{
mm[i] = ((i & (i - )) == ) ? mm[i - ] + : mm[i - ];
dp[i][] = i;
}
for (int j = ; j <= mm[n]; ++j)
{
for (int i = ; i + ( << j) - <= n; ++i)
{
dp[i][j] = rmq[dp[i][j - ]] < rmq[dp[i + ( << (j - ))][j - ]] ? dp[i][j - ] : dp[i + ( << (j - ))][j - ];
}
}
}
inline int query(int a, int b)
{
if (a > b) swap(a, b);
int k = mm[b - a + ];
return rmq[dp[a][k]] <= rmq[dp[b - ( << k) + ][k]] ? dp[a][k] : dp[b - ( << k) + ][k];
}
}st; inline void DFS(int u, int pre, int dep)
{
F[++tot] = u;
rmq[tot] = dep;
P[u] = tot;
for (int it = head[u]; ~it; it = edge[it].nx)
{
int v = edge[it].to;
if (v == pre) continue;
dist[v] = dist[u] + ;
DFS(v, u, dep + );
F[++tot] = u;
rmq[tot] = dep;
}
} inline void Lca_Init(int root, int node_num)
{
DFS(root, root, );
st.init( * node_num - );
} inline int query_lca(int u, int v)
{
return F[st.query(P[u], P[v])];
} inline int find(int x)
{
if (pre[x] != x)
pre[x] = find(pre[x]);
return pre[x];
} inline void join(int x, int y)
{
int fx = find(x), fy = find(y);
if (fx != fy)
pre[fx] = fy;
} inline void Kruskal()
{
sort(ed + , ed + + cnt);
int Count = ;
for (int i = ; i <= cnt; ++i)
{
int u = ed[i].to, v = ed[i].nx;
if (find(u) == find(v)) continue;
addedge(u, v, ed[i].w); addedge(v, u, ed[i].w);
join(u, v);
++Count;
if (Count == n * m) return;
}
return;
} inline void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
Init();
char dir; ll w; int u, v;
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
{
for (int k = ; k < ; ++k)
{
scanf(" %c %lld", &dir, &w);
u = (i - ) * n + j;
if (dir == 'X') continue;
if (dir == 'D') v = i * n + j;
else if (dir == 'R') v = (i - ) * n + j + ;
ed[++cnt] = Edge(u, v, w);
}
}
}
Kruskal(); Lca_Init(, n * m);
int x[], y[];
scanf("%d", &q);
for (int i = ; i <= q; ++i)
{
scanf("%d%d%d%d", &x[], &y[], &x[], &y[]);
u = (x[] - ) * n + y[], v = (x[] - ) * n + y[];
int lca = query_lca(u, v);
//printf("%d %d %d\n", u, v, lca);
printf("%lld\n", dist[u] + dist[v] - * dist[lca]);
} }
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

K. Morgana Net

留坑。

ACM-ICPC 2018 徐州赛区网络预赛 Solution的更多相关文章

  1. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心)

    ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心) Trace 问答问题反馈 只看题面 35.78% 1000ms 262144K There's a beach in t ...

  2. ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)

    ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer ...

  3. 计蒜客 1460.Ryuji doesn't want to study-树状数组 or 线段树 (ACM-ICPC 2018 徐州赛区网络预赛 H)

    H.Ryuji doesn't want to study 27.34% 1000ms 262144K   Ryuji is not a good student, and he doesn't wa ...

  4. ACM-ICPC 2018 徐州赛区网络预赛 B(dp || 博弈(未完成)

    传送门 题面: In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl n ...

  5. ACM-ICPC 2018 徐州赛区网络预赛 B. BE, GE or NE

    In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named &qu ...

  6. ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study

    262144K   Ryuji is not a good student, and he doesn't want to study. But there are n books he should ...

  7. ACM-ICPC 2018 徐州赛区网络预赛 F. Features Track

    262144K   Morgana is learning computer vision, and he likes cats, too. One day he wants to find the ...

  8. ACM-ICPC 2018 徐州赛区网络预赛 I. Characters with Hash

    Mur loves hash algorithm, and he sometimes encrypt another one's name, and call him with that encryp ...

  9. ACM-ICPC 2018 徐州赛区网络预赛 D 杜教筛 前缀和

    链接 https://nanti.jisuanke.com/t/31456 参考题解  https://blog.csdn.net/ftx456789/article/details/82590044 ...

随机推荐

  1. laravel安装 redis 并驱动 session

    1)composer 安装 redis composer require predis/predis 如果感兴趣,可以看一下这里 2)配置 redis 连接(config/database.php 配 ...

  2. MySQL性能优化(三)-- 索引

    一.什么是索引及索引的特点 索引是一种数据结构 索引的特点:查找速度快,排好序,数据结构 索引的数据结构类型有:BTREE索引和HASH索引,下面展示的是BTREE索引. BTREE:balance ...

  3. Linux下Redis集群环境的搭建

    一.安装redis(使用redis3.0版本) 1.需要gcc环境,如果没有执行命令安装gcc yum install gcc-c++ 2.下载redis3.0的源码包并上传至服务器 3.解压源码包 ...

  4. c++11——std::function和bind绑定器

    c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值. 可调用对象 c++中的可调用对象存在以下几类: (1)函数指针 (2)具有ope ...

  5. 浅析HTTPS与SSL原理

    版权声明:本文由盛旷 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/134 来源:腾云阁 https://www.qclo ...

  6. JSTL中&#60;c:set&#62;标签的用法

    <c:set>标签有两种不同的属性设置:var和target. var“版本”用于设置作用域属性,target“版本”用于设置bean属性或Map值. 这两个版本都有两种形式:有标签体和没 ...

  7. 用C或C++为Python编写模块

    1.使用c或c++编写对应的函数例如: //modtest.c int abs(int number){ ){ return -number; } else{ return number; } } 2 ...

  8. 封装自己的getClassName函数

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. mysql 内连接原理

  10. html5新属性contenteditable 对于那些不可编辑的标签,现在都可以编辑了

    contenteditable = true 表示该html标签的内容可以编辑,对于那些不可编辑的标签,现在都可以编辑了.