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. RF-template使用

    在测试案例中,可以使用template设置进行数据驱动的测试,template设置方法: 在设置项中填写模板的关键字名称,测试案例本身只能包含template关键字使用的数据: *** Setting ...

  2. linux IP 设置

    修改ip地址即时生效:# ifconfig eth0 192.168.1.102 netmask 255.255.255.0启动生效:修改/etc/sysconfig/network-scripts/ ...

  3. JS对象添加新的字段

    var test={name:"name",age:"12"}; test.id = "12345"; 直接定义添加就成了

  4. deferred对象(摘自别人的文章)

    对jQuery中的deferred对象的整体认识: Deferred是个工厂类,返回的是内部构建的deferred对象 tuples 创建三个$.Callbacks对象,分别表示成功,失败,处理中三种 ...

  5. Android Fingerprint系列之google原生界面

    ENV: Anroid M 6.0 1. 录入指纹引导界面 2.指纹要求先设置密码或验证密码界面(已经添加安全密码) 3.引导用户寻找指纹传感器 4.录入指纹界面 5.指纹录入结束界面

  6. 2.实现官网环境, 搭建HTTP服务器

    1.建立 HTTP 服务器 Node.js 是为网络而诞生的平台,但又与 ASP.PHP 有很大的不同,究竟不同在哪里呢?如果你有 PHP 开发经验,会知道在成功运行 PHP 之前先要配置一个功能强大 ...

  7. 【BZOJ4515】[Sdoi2016]游戏 树链剖分+线段树

    [BZOJ4515][Sdoi2016]游戏 Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 1234567 ...

  8. 【Android】 ImageView.ScaleType设置图解

    ImageView的Scaletype决定了图片在View上显示时的样子,如进行何种比例的缩放,及显示图片的整体还是部分,等等. 设置的方式包括: 1. 在layout xml中定义android:s ...

  9. npm安装出错的时候,如何使用国内的镜像!--解决办法

    在前端开发领域,Node已经很普遍了,使用Node就会使用到一些包.所以常用的 npm 就会经常使用得到,但是在使用 npm 安装一些包的过程中,会发现安装的速度会很慢,而且很多时候直接安装不了. 百 ...

  10. 微信小程序 --- 下拉刷新上拉加载

    查看文档看到:page()函数注册页面的时候,有 onPullDownRefresh 监听用户下拉动作,onReachBottom 页面上拉触底事件的函数. 在小程序里,用户顶部下拉是默认禁止的,我们 ...