题目链接:2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest

A. Rikka with Minimum Spanning Trees

题意:

给出一个随机算法生成边的信息,然后求最小生成树的个数以及其权值的乘积。

题解:

这个随机算法有点神奇...基本不会有重复的边出现,所以其实只用求MST就行了。当然,其实通过样例也可以猜出来,样例生成了1W条边,但最后的answer就为最小生成树权值,所以可以直接根据这个来猜一发,注意一下判断是否连通就行了。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+;
const int MAXM = 3e5+;
const int MOD = 1e9+;
const double eps = 1e-;
typedef unsigned long long ull;
#define rep(i,a,b) for(int i = (a);i<=(b);i++)
struct Edge{
int u,v;
ull w;
bool operator <(const Edge &ds)const{
return w<ds.w;
}
}e[MAXM];
int n,m,fa[MAXN];
int t,tot;
//double G[MAXN][MAXN];
ull k1,k2;
ull ans=;
ull xorShift128Plus(){
ull k3=k1,k4=k2;
k1=k4;
k3 ^= k3<<;
k2 = k3 ^ k4 ^ (k3 >>) ^(k4 >>);
return k2 +k4;
}
void gen(){
cin >>n >>m >>k1 >>k2;
int u,v;
ull w;
tot = ans = ;
rep(i,,m){
u = xorShift128Plus()%n+;
v = xorShift128Plus()%n+;
w = xorShift128Plus();
if(u == v) continue ;
//cout <<u<<' ' <<v<<' ' <<w <<'\n';
e[++tot] = {u,v,w};
}
}
int find(int x){
return x==fa[x]?x:fa[x] = find(fa[x]);
}
bool kruskal(){
int ss=;
sort(e+,e++tot);
rep(i,,n)fa[i] =i;
rep(i,,tot){
int a = find(e[i].u),b =find(e[i].v);
if(a!=b){
fa[a] =b;
ans = (ans +e[i].w%MOD)%MOD;
ss++;
}
}
return ss==n-;
}
int main() {
ios::sync_with_stdio(false);cin.tie() ;
cin >>t;
while(t--){
gen();
if(!kruskal()){
cout << <<'\n';
}else{
cout << ans <<'\n';
}
}
return ;
}

G. Rikka with Intersections of Paths

题意:

树上给出若干条简单路径,问有多少选k条路径的方案,满足这些路径的交至少有一个点。

题解:

考虑求出LCA,因为树上简单路径至少存在一个交点为至少一条路径的两端点的LCA,同时可以利用树上差分求出有多少条路径经过当前点。

之后计算贡献就行了,但是这里直接计算C(cnt, k)会有重复计算的,我们这里可以考虑刚才关于LCA的性质,求出每个点为多少条路径端点的LCA,个数记为pi,那么最后答案就是C(cnt,k) - C(cnt - pi,k),此时选出的路径中,至少有一条路径的两端点的LCA为当前点,此时就不会重复计算了。因为一条路径的LCA只有一个,我们只会计算经过LCA时的贡献。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + , MOD = 1e9 + ;
int T, n, m, k;
struct Edge{
int u,v,next;
}e[N << ];
int head[N],tot;
void adde(int u, int v) {
e[tot].v = v;
e[tot].next = head[u] ;
head[u] = tot++ ;
}
int deep[N], st[N][], sum[N], cnt[N];
ll fac[N], inv[N];
void dfs(int u, int d, int fa) {
st[u][] = fa;
deep[u] = d;
for(int i = head[u]; i != -; i = e[i].next) {
int v = e[i].v;
if(v == fa) continue ;
dfs(v, d + , u);
}
}
ll qp(ll a, ll b) {
ll ans = ;
while(b) {
if(b & ) ans = ans * a % MOD;
a = a * a % MOD;
b >>= ;
}
return ans ;
}
void init() {
for(int i = ; i <= ; i++)
for(int j = ; j <= n ; j++)
st[j][i] = st[st[j][i - ]][i - ];
}
int LCA(int x, int y) {
if(deep[y] > deep[x]) swap(x , y) ;
while(deep[x] != deep[y]) {
int d = deep[x] - deep[y] ;
for(int i = ; i <= ; i++) {
if(d >> i & ) x = st[x][i] ;
}
}
if(x == y) return x ;
for(int i = ; i >= ; i--) {
if(st[x][i] != st[y][i]) {
x = st[x][i] ;
y = st[y][i] ;
}
}
return st[x][] ;
}
void pre(int u, int fa) {
for(int i = head[u] ; i != -; i = e[i].next) {
int v = e[i].v;
if(v == fa) continue ;
pre(v , u);
sum[u] += sum[v] ;
}
}
ll C(ll a ,ll b) {
if(b == || a < b) return ;
return fac[a] * inv[b] % MOD * inv[a - b] % MOD;
}
ll calc(ll x) {
ll ans = C(sum[x], k);
ans = ((ans - C(sum[x] - cnt[x], k) % MOD ) % MOD + MOD ) % MOD;
return ans ;
}
int main() {
ios::sync_with_stdio(false);cin.tie();
fac[] = ;
inv[] = ;
for(int i = ; i < N; i++) {
fac[i] = fac[i - ] * i % MOD;
inv[i] = qp(fac[i] , MOD - ) ;
}
cin >> T;
while(T--) {
memset(head,-,sizeof(head)); tot = ;
cin >> n >> m >> k ;
for(int i = ; i < n ; i++) {
int u, v;
cin >> u >> v;
adde(u, v);adde(v, u);
}
dfs(, , );
init() ;
for(int i = ; i <= m ;i++) {
int u, v;
cin >> u >> v ;
int x = LCA(u , v);
sum[u]++;sum[v]++;
sum[x]--;sum[st[x][]]--;
cnt[x]++;
}
pre(, ) ;
ll ans = ;
for(int i = ; i <= n; i++) {
ans = (ans + calc(i)) % MOD ;
}
cout << ans << '\n' ;
for(int i = ; i <= n ; i++) deep[i] = sum[i] = cnt[i] = ;
}
return ;
}

H. Rikka with A Long Colour Palette

题意:

给出n个区间,k个颜色,现在给区间染色,问怎么染色能使得覆盖有所有颜色的区间长度最大。

题解:

染色过程考虑贪心。我们先按照区间左端点排序,然后依次涂颜色,颜色涂完了之后该怎么涂呢?假设当前左端点为L,并且在之前的区间中,有Ri,Rj,Rk满足Ri < L  < Rj < Rk,那么此时我们涂Ri的颜色肯定是最优的;如果不存在一个Ri,满足L < Ri,这时我们也只需要涂处于最左端的Ri,因为这样可以尽可能地增多所有颜色覆盖的区间长度。

最后就考虑如果计算答案了,将所有点排序后记录左端点为1,右端点为-1,累计前缀和,当和大于等于k时更新答案即可。

代码如下:

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 2e5 + ;
int T;
int n, k, cnt;
pair<pii,int> a[N << ];
int col[N], has[N], answer[N];
struct Node {
int l, r, id ;
bool operator < (const Node &A) const {
if(l == A.l) return r < A.r;
return l < A.l;
}
}p[N];
int main() {
ios::sync_with_stdio(false);cin.tie();
cin >> T;
while (T--) {
cin >> n >> k;
cnt = ;
for(int i = ; i <= n ; i++) {
int l, r;
cin >> l >> r;
p[i] = Node{l,r,i};
}
if(n < k) {
cout << << '\n' ;
for(int i = ; i < n; i++)
cout << << ' ' ;
cout << << '\n' ;
continue ;
}
sort(p + , p + n + );
priority_queue <pii> q;
for(int i = ; i <= k ; i++) {
q.push(mp(, i)) ;
}
for(int i = ; i <= n ; i++) {
int now = q.top().second;q.pop();
answer[p[i].id] = col[i] = now;
q.push(mp(-p[i].r,now)) ;
}
for(int i = ; i <= n ;i++) {
a[++cnt] = mp(mp(p[i].l,col[i]),) ;
a[++cnt] = mp(mp(p[i].r,col[i]),-) ;
}
sort(a + , a + cnt + ) ;
int ans = , cur = ;
for(int i = ; i <= cnt ; i++) {
if(has[a[i].first.second]) cur--;
has[a[i].first.second] += a[i].second ;
if(has[a[i].first.second]) cur++;
if(cur >= k )
ans += a[i + ].first.first - a[i].first.first;
}
cout << ans << '\n' ;
for(int i = ; i < n ; i++) cout << answer[i] << ' ';
cout << answer[n] << '\n' ;
for(int i = ; i <= k ; i++) has[i] = ;
}
return ;
}

I. Rikka with Sorting Networks

题意:

给出n个数,有k个排序器,每个排序器会使得au < av,即让他们的位置相对有序,问有多少个排列,最后通过这k个排序器后,形成的序列最长上升子序列至少为n - 1。

题解:

满足条件的最长上升子序列个数为(n - 1) ^ 2 + 1个,由于数据范围很小,我们直接构造出来爆搜求解即可。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ;
int a[N], b[N] ;
int n, k, T, mod;
int from[N], to[N] ;
int ans;
void dfs(int i, int f) {
if(i == ) {
ans += f;
if(ans >= mod) ans -= mod;
return ;
}
if(a[from[i]] < a[to[i]]) {
dfs(i - , f) ;
swap(a[from[i]], a[to[i]]) ;
dfs(i - , f) ;
swap(a[from[i]], a[to[i]]) ;
}
}
int main() {
ios::sync_with_stdio(false);cin.tie();
cin >> T;
while(T--) {
cin >> n >> k >> mod;
for(int i = ; i <= k ; ++i) cin >> from[i] >> to[i] ;
for(int i = ; i <= n ; ++i) a[i] = i ;
ans = ;
dfs(k, ) ;
for(int i = ; i < n ; ++i) {
swap(a[i], a[i + ]);
dfs(k, -);
swap(a[i], a[i + ]);
}
for(int take = ; take <= n ; ++take) {
for(int i = ; i <= n ; ++i) {
if(i == take) continue ;
int cur = ;
for(int j = ; j <= n ; ++j) {
if(cur == take - ) cur++;
if(i == j) a[j] = take ;
else a[j] = ++cur;
}
dfs(k , );
}
}
cout << ans << '\n';
} return ;
}

2018-2019 ACM-ICPC 徐州区域赛 部分题解的更多相关文章

  1. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...

  2. 2016 年 ACM/ICPC 青岛区域赛 Problem C Pocky

    昨晚乱入学弟的训练赛,想了一下这个题.推导的过程中,加深了对公理化的概率论理解.$\newcommand{\d}{\mathop{}\!\mathrm{d}}$ 解法一 考虑 $ d < L$ ...

  3. Known Notation括号匹配类问题(2014年ACM/ICPC 亚洲区域赛牡丹江)

    题意: 给你数字或 * 的串,你可以交换一个*和数字.在最前面添1.在一个地方插入*,问你使串满足入栈出栈的(RNP)运算法则. 思路: 引用:https://blog.csdn.net/u01158 ...

  4. Digit sum (第 44 届 ACM/ICPC 亚洲区域赛(上海)网络赛)进制预处理水题

    131072K   A digit sum S_b(n)Sb​(n) is a sum of the base-bb digits of nn. Such as S_{10}(233) = 2 + 3 ...

  5. 2018 ICPC 徐州网络赛

    2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution ...

  6. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  7. 2018.11.25 AMC-ICPC 亚洲区域赛(焦作站)吊银

    11月23日 大清早,跟着wyb的脚步,早起跑过去听方伟的编译原理,然鹅一点都没听进去,在焦作胡辣汤群里疯狂灌水... 听说焦作那边冷得不行,前一天看天气预报说那边已经是2℃了,都快零下了,然鹅学校里 ...

  8. 2016年11月ACM/ICPC亚洲区北京赛赛后总结

    2016年11月12到11月13为期两天的比赛,这是我们这个对第一次去打亚洲区域赛,经过这次比赛,我认识到了自己与别人的差距,也许我们与别人的起点不同,但这不是理由. 这次的比赛12号的热身赛两点开始 ...

  9. 2014ACM/ICPC亚洲区域赛牡丹江站汇总

    球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doub ...

随机推荐

  1. HIVE中的数据怎么导出到hdfs或本地呢

    思路一:重定向 在我不知道工具 ,也不熟悉HIQL语法的情况下,没办法了,只有选择一个最简单粗暴的方法,重定向. 在shell中使用 hive -e 可以在shell中执行hive命令,hive -f ...

  2. phpcms v9如何给父级单页栏目添加内容

    对于phpcms单页的调用相信大家都应该没问题,那么如果我们在后台添加的单页有二层甚至更多的时候,这样在管理内容上是没有给父级栏目添加内容这一功能的!那么我们该怎么实现这个功能并调用呢? 首先我们要修 ...

  3. HP VC模块Shared uplink Sets配置参考

    首先配置MAC地址的分配方式 在左侧导航栏中,点解"MAC Addresses" 选择VC分配MAC地址,并且选择一个合适的地址段,点击"Apply"继续 在弹 ...

  4. 如何在HPUX的终端提示符前显示当前登录用户信息和所在目录

    修改/etc/default/profile文件,在最后加上如下内容: case $LOGNAME in     'root')     PS1="$LOGNAME@$(hostname): ...

  5. 【MySQL 数据库】MySQL目录

    目录 [第一章]MySQL数据概述 [第二章]MySQL数据库基于Centos7.3-部署 [MySQL解惑笔记]Centos7下卸载彻底MySQL数据库 [MySQL解惑笔记]忘记MySQL数据库密 ...

  6. 亚马逊CEO贝索斯致股东信:阐述公司未来计划

    亚马逊CEO 杰夫·贝索斯(Jeff Bezos)今天发布年度股东信, 详细描述了亚马逊的产品.服务和未来计划,当然,信中并没有任何的硬数据,比如说亚马逊Kindle的销量等等.但这封信也包括一些颇令 ...

  7. Wormholes POJ 3259(SPFA判负环)

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  8. Java变量声明,实例化,问题

    1.变量在输出前必须实例化,这是因为只有声明,没有分配内存空间 在这种情况下会报错 2.实例化后,尽管没有赋值,可能是默认了吧,但也不会输出null,什么也没有输出 上面的理解可能是错的,a赋值了,就 ...

  9. Alpha 冲刺(9/10)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 多次测试软件运行 学习OPENMP ...

  10. SGU 199 Beautiful People 二维最长递增子序列

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20885 题意: 求二维最长严格递增子序列. 题解: O(n^2) ...