Wannafly挑战赛26 题解

Wannafly挑战赛26

题目连接

https://www.nowcoder.com/acm/contest/212#question

A. 御坂网络

枚举圆心所在的位置,O(n)O(n)O(n) 检查即可,总时间复杂度为O(n2)O(n^2)O(n2)

B. 冥土追魂

这题比较坑,我感觉题意叙述有问题,总之也是一道水题,题解略去.

C. 七彩线段

题解

考虑到只有777种颜色,因此可以枚举最后选出线段的颜色组合,272^727种情况.

线段选法类似于会议安排,对于两个颜色相同的线段,我们必然优先选择右端点小的,因此我们第一步需要对线段以右端点从小到大进行排序.

预处理出数组pre[i]pre[i]pre[i],表示与线段iii不想交的右端点最大的线段是谁.

然后考虑状态压缩dpdpdp:

dp[i][S]dp[i][S]dp[i][S]表示考虑前iii个线段,已经选出来的线段颜色组合为SSS,所取得的最大长度.

转移方程dp[i][S∣(1&lt;&lt;color[i])]=max(dp[pre[i]][S],dp[i−1][S(1&lt;&lt;color[i])])dp[i][S | (1 &lt;&lt; color[i])] = max(dp[pre[i]][S],dp[i-1][S(1&lt;&lt;color[i])])dp[i][S(1<<color[i])]=max(dp[pre[i]][S],dp[i1][S(1<<color[i])])

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
#define clr(x) memset(x,0,sizeof(x))
#define setinf(x) memset(x,0x3f,sizeof(x))
struct seg{int l,r,c;bool operator<(const seg& sg)const{return r < sg.r;}
};
std::vector<seg> segs;
int n,m;
long long dp[100007][1<<7];
int used[1 << 7];inline int cnt(int x) {int res = 0;while (x) {res++;x -= x & -x;}return res;
}
int pre[100007];
int main() {std::cin >> n >> m;for(int S = 0;S < (1<<7);++S) {if(cnt(S) == m) used[S] = 1;}for(int i = 0;i < n;++i) {int l,r,c;std::cin >> l >> r >> c;c--;segs.push_back((seg){l,r,c});}std::sort(segs.begin(),segs.end());for(int i = 0;i < n;++i) {int id = (std::lower_bound(segs.begin(),segs.end(),(seg){0,segs[i].l,0}) - segs.begin());--id;pre[i] = id;}long long ans = -1;dp[0][1<<segs[0].c] = segs[0].r - segs[0].l;for(int i = 1;i < n;++i) {dp[i][1 << segs[i].c] = segs[i].r - segs[i].l;for(int S = 0;S < (1<<7);++S) {dp[i][S] = std::max(dp[i][S],dp[i-1][S]);}if(pre[i] >= 0)for(int S = 0;S < (1 << 7);++S) {int nS = S|(1<<segs[i].c);if(dp[pre[i]][S])dp[i][nS] = std::max(dp[i][nS],dp[pre[i]][S] + segs[i].r - segs[i].l);}for(int S = 0;S < (1 << 7);++S) {if(used[S] && dp[i][S] > ans)ans = dp[i][S];	}}if(ans == 0) ans = -1;std::cout << ans << std::endl;
}

D.禁书目录

题解

我们考虑每种颜色被在排列中被计数了多少次.

[0]结论: 一本书不会消失当且仅当所有aaa大于等于它的书都在它的右边.

因此假设有ttt本书其ai≥axa_i \ge a_xaiax,只考虑这ttt本书的排列,书xxx被看见的概率是1t\frac{1}{t}t1.

[1]假设有书ax&gt;aya_x &gt; a_yax>ay,且ai≥axa_i \ge a_xaiax的有txt_xtx本书,ai≥aya_i \ge a_yaiay的有tyt_yty本书,显然tx&lt;tyt_x \lt t_ytx<ty,我们希望求出xxxyyy都没有出现的概率:

txt_xtx本书的相互排列中,书xxx必然不能出现在第一个位置,这样概率是tx−1tx\frac{t_x-1}{t_x}txtx1.然后tyt_yty本书中yyy也不能出现在第一个位置,txt_xtx的排列对书yyy的选择没有影响,因此概率是ty−1ty\frac{t_y-1}{t_y}tyty1,乘起来就是ty−1ty∗tx−1tx\frac{t_y-1}{t_y}*\frac{t_x-1}{t_x}tyty1txtx1.

[2]假设有书ax=aya_x = a_yax=ay,且ai≥axa_i \ge a_xaiax的书有ttt本,我们希望求出书xxxyyy都没有出现的概率.先不考虑axa_xax,那么aya_yay不出现的概率是t−2t−1\frac{t-2}{t-1}t1t2,再考虑axa_xax不出现的概率是t−1t\frac{t-1}{t}tt1,乘起来就是t−2t\frac{t-2}{t}tt2,可以猜测有kkk本书aaa相同时,且ai≥aa_i \ge aaia的书有ttt本,那么这kkk本书都没出现的概率是t−kt\frac{t-k}{t}ttk

ps:我们为什么要求[2]呢,为什么ax=aya_x = a_yax=ay时候,求两者都不出现的概率时候不能直接使用[0]结论呢?
这是因为
当对axa_xax使用结论[0]时候,默认aya_yayaxa_xax右侧,而再对aya_yay使用结论[0]时候,默认axa_xaxaya_yay右侧,这样就出现了矛盾,因此,当两者aaa相等时,就不能直接用结论000了,而需要扩展一下.

结合[1][2]两个结论,我们枚举每一种颜色,计数这些颜色的书每一本都没有被看到的概率.
然后最后用111减去这个概率再乘以n!n!n!即是这部分颜色的贡献.

举个例子,当颜色为ccc的书为
a1&lt;a3=a5&lt;a6&lt;a7a_1 &lt; a_3 = a_5 &lt; a_6 &lt; a _ 7a1<a3=a5<a6<a7 时候是,对答案的贡献就是

n!∗(1−t1−1t1∗t3−2t3∗t6−1t6∗t7−1t7)n! * (1-\frac{t_1-1}{t_1}*\frac{t_3-2}{t_3}*\frac{t_6-1} {t_6}*\frac{t_7-1}{t_7})n!(1t1t11t3t32t6t61t7t71)

其中tit_iti表示不小于aia_iai的书的本数.

代码

#include <iostream>
#include <algorithm>
#include <map>#define pr(x) std::cout << #x << ":" << x << std::endlconst int N = 1000007;typedef long long ll;
typedef std::pair<int,int> pii;
const ll P = 998244353;
std::map<int,ll> mp;
ll mod_pow(ll x,ll n) {ll res = 1;while(n) {if(n & 1) res = res * x % P;x = x * x % P;n >>= 1;}return res;
}
int n;
pii ps[N];
int main() {std::ios::sync_with_stdio(false);std::cin >> n;for(int i = 1;i <= n;++i) {int a,b;std::cin >> a >> b;ps[i-1] = (pii){a,b};}std::sort(ps,ps+n);ll ans = 0;ll nn = 1;for(int i = 1;i <= n;++i) nn = nn * i % P;int last = 0;for(int i = 0;i < n ;++i) {int pos = i;while(pos < n-1 && ps[pos] == ps[pos+1])++pos;if(mp.count(ps[pos].second) == 0) mp[ps[pos].second] = 1;if(ps[i].first != ps[last].first) last = i;ll big = n - last;mp[ps[pos].second] = mp[ps[pos].second] * (big - (pos - i + 1)) % P* mod_pow(big,P-2) % P;i = pos;}for(auto &p : mp) {ans = (ans + (nn * (1 + P - p.second) % P)) % P;}std::cout << ans << std::endl;
}

E.蚂蚁开会

待解决

F.msc的棋盘

题解

这其实是一道现寻找充要条件,然后使用dpdpdp计数的题.

如果给出a数组a数组a(行数组),和b数组b数组b(列数组),要进行判定,那么我们想到了用网络流进行判定,如果满流的话,就表示判定成功.

n=4,m=2,b[1]=1,b[2]=3n = 4,m = 2,b[1] = 1,b[2] = 3n=4,m=2,b[1]=1,b[2]=3时候,
左边一排点有444个,右边一排点有222个,且两排点之间两两有边容量为111.源点向第一排点连边容量为a[i]a[i]a[i],第二排点向汇点连边,容量为b[i]b[i]b[i].

sum=∑b[i]sum = \sum{b[i]}sum=b[i]

根据最大流最小割定理,也就是说图的最小割必然要=sum= sum=sum

考虑一个割选取了左边xxx个点,右边yyy个点,那么必然会选择左边a[i]a[i]a[i]最小的前xxx个点,同理右边会选择b[i]b[i]b[i]最小的前yyy个点.同样在剩下的没有选择的边中中间容量为111的边都要被切掉.

sa,sbsa,sbsa,sb表示a,ba,ba,b排好序的前缀和.

割(x,y)=sa[x]+sb[y]+(n−x)(m−y)≥sum割(x,y) = sa[x] + sb[y] + (n-x)(m-y) \ge sum(x,y)=sa[x]+sb[y]+(nx)(my)sum

且由于最大流≤sum\le sumsum,所以保证了有割=sum割=sum=sum.

因此我们就得到了一个充要条件.

那就是所有的割割必然要≥sum\ge sumsum,求方案数.

相当于要把sumsumsum个棋子,分给每一行,使得割割满足≥sum\ge sumsum,的方案数.直觉告诉我们要用dpdpdp来做.

定义dp[i][j][k]dp[i][j][k]dp[i][j][k]表示考虑a[i]a[i]a[i]iii小的行,且最大行的a[i]≤ja[i] \le ja[i]j,且sa[i]=ksa[i] = ksa[i]=k的方案数.

转移方程:

dp[i+t][j+1][k+t(j+1)]+=dp[i][j][k]Cn−it,且0≤t≤n−idp[i+t][j+1][k+t(j+1)] += dp[i][j][k]C_{n-i}^{t},且0 \le t \le n-idp[i+t][j+1][k+t(j+1)]+=dp[i][j][k]Cnit,0tni

观察dpdpdp方程,只有第二维严格递增,因此转移的时候我们先枚举第二维,然后再枚举第一维和第三维,这样保证了dpdpdp的无后效性.

代码

#include <cstdio>
#include <iostream>
#include <algorithm>#define pr(x) std::cout << #x << ":" << x << std::endl
typedef long long ll;
const ll P = 1000000007;
const int N = 51;
int n,m;
ll dp[N][N][N*N]; 
// dp[i][j][k] 表示前i小的行都已经考虑完,第i小的行有j个棋子,且前i行总棋子数量为k的可能的方案数.int sa[N],sb[N];
//sa[i]表示前i小的行棋子总数的最小限度
ll C[N][N];
void init() {C[0][0] = 1;for(int i = 1;i < N;++i) {C[i][0] = 1;for(int j = 1;j <= i;++j) {C[i][j] = (C[i-1][j-1] + C[i-1][j]) % P;}}
}
ll fC(int n,int m) {if(m > n || m < 0) return 0;return C[n][m];
}
void add(ll &x,ll y) {x = x + y;if(x > P) x -= P;
}int main() {init();std::cin >> n >> m;for(int i = 1;i <= m;++i) std::cin >> sb[i];std::sort(sb+1,sb+1+m);for(int i = 1;i <= m;++i)sb[i] += sb[i-1];for(int i = 1;i <= n;++i) {int mi = 2500;for(int j = 1;j <= m;++j) {mi = std::min(mi,sb[j] + (n-i)*(m-j));}sa[i] = sb[m] - mi;}int lim = sb[m];for(int i = 0;i <= n && 0 >= sa[i];++i) {dp[i][0][0] = fC(n,i);}for(int j = 0;j <= m;++j) {for(int i = 0;i <= n;++i) {for(int k = 0;k <= lim;++k) {if(dp[i][j][k] == 0) continue;for(int t = 0;i+t <= n && k + t*(j+1) <= lim&& k + t*(j+1) >= sa[i+t];++t) {add(dp[i+t][j+1][k+t*(j+1)],dp[i][j][k]*fC(n-i,t)%P);}}}}std::cout << dp[n][m][lim] << std::endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初一模拟赛总结(3.16)

成绩&#xff1a; rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4111lyflyflyf210210210303030100100100000808080222hkyhkyhky190190190100100100000101010808080333fyfyfy120120120100100100000202020000444tjhtjhtjh100100100100100100000000000555wjjwj…

牛客挑战赛43C-最优公式【二分】

正题 题目链接:https://ac.nowcoder.com/acm/contest/7413/C 题目大意 给一个序列AAA&#xff0c;求两个a,ba,ba,b使得∑i1n∑j1nmax{∣Ai−a∣,∣Aj−b∣}\sum_{i1}^n\sum_{j1}^nmax\{|A_i-a|,|A_j-b|\}i1∑n​j1∑n​max{∣Ai​−a∣,∣Aj​−b∣}最小。 解题思路 因为是取…

好代码是管出来的——Git的分支工作流与Pull Request

上一篇文章好代码是管出来的——使用Git来管理源代码 介绍了常用的版本控制工具以及git的基本用法&#xff0c;从基本用法来看git与其它的版本控制工具好像区别不大&#xff0c;都是对代码新增、提交进行管理&#xff0c;可以查看提交历史、代码差异等功能。但实际上git有一个重…

牛客练习赛29 题解

牛客练习赛29 A. 可持久化动态图上树状数组维护01背包 题解 这题跟标题没有任何关系… 贪心的使得负数删除的时候下标尽可能大,然后正数的时候下标尽可能小. 观察到每个数下标最大的时候就是它的初始下标,下标的最小值是1. 然后贪心一下就好了. 代码 #include <iost…

【Floyed】小萨的烦恼(ssl 1624)

小萨的烦恼 ssl 1624 题目大意&#xff1a; 一个无向图&#xff0c;可以使其中一条道路的值除以2&#xff0c;求两个点之间的最短路 原题&#xff1a; Description 圣诞节又要到了&#xff01;小萨希望和自己心仪的MM一起出去度过一个浪漫的的圣诞节。他进行了详尽的准备…

好代码是管出来的——使用GitHub

前面的文章介绍了Git的基本概念和用法&#xff0c;本文则是基于GitHub的一个实践介绍&#xff0c;主要内容有&#xff1a;GitHub简介个人与组织仓库的创建与维护Fork与pull request小结GitHub简介GitHub是一个Git的远程代码托管平台&#xff0c;它除了提供代码托管外&#xff0…

Wannafly挑战赛24

Wannafly挑战赛24 题目连接 https://www.nowcoder.com/acm/contest/186#question A.石子游戏 题解 注意到当石子个数为偶数的时候,每回合都会减少一堆偶数石子,因此,先手必胜. 我们可以不考虑奇数堆石子,因为必胜方始终可以动偶数堆. 当必败方将奇数堆分成一堆偶数和一堆…

【模拟】正方形

正方形 题目大意&#xff1a; 有三个人&#xff0c;一人一笔的画正方形&#xff0c;每个正方形是上一个正方形每条边上的中点连接而成的&#xff0c;求每个人画了多长 原题&#xff1a; 题目描述 又到暑假啦&#xff0c;Conan, Ayumi, Mitsuhiko, Genta一起到Hakase家愉快…

P3975-[TJOI2015]弦论【SAM】

正题 题目链接:https://www.luogu.com.cn/problem/P3975 题目大意 给一个字符串sss和t,kt,kt,k。求字符串sss第kkk大的子串。 当T0T0T0时&#xff0c;相同的子串算一个当T1T1T1时&#xff0c;不同位置的相同子串算不同的串 解题思路 当T0T0T0时很简单&#xff0c;对于每个位…

【DP】跳格子

跳格子 题目大意&#xff1a; 有一堆格子&#xff0c;可以往前跳不超过当前格子上的数的步数&#xff0c;从1跳到最后一格最少要跳多少 原题&#xff1a; 题目描述 大家都说要劳逸结合&#xff0c;Ayumi, Mitsuhiko, Genta画完方格就出去运动啦&#xff01; 他们来到了一片…

.NET Core微服务之基于IdentityServer建立授权与验证服务

一、IdentityServer的预备知识要学习IdentityServer&#xff0c;事先得了解一下基于Token的验证体系&#xff0c;这是一个庞大的主题&#xff0c;涉及到Token&#xff0c;OAuth&OpenID&#xff0c;JWT&#xff0c;协议规范等等等等&#xff0c;园子里已经有很多介绍的文章了…

模拟退火求解TSP问题

模拟退火求解TSP问题 模拟退火算法步骤 1.寻找下一个解 2.计算下一个解的能量 3.决定是否接受这个解 4.降温 算法模板 double randfloat() {return rand()/(RAND_MAX0.0); }double T0 1000000,Tk 1,T T0,d 0.9999; int x initx();//当前解(初始解) int ansE,nowE;//全…

P2444-[POI2000]病毒【AC自动机】

正题 题目链接:https://www.luogu.com.cn/problem/P2444 题目大意 nnn个字符串&#xff0c;求有没有一个无限的字符串不包含任何一个给出的字符串。 解题思路 考虑ACACAC自动机的匹配方式&#xff0c;不过每次我们可以每次在构出的TrieTrieTrie树上随意走&#xff08;就是求完…

【模拟】2048

2048 题目大意&#xff1a; 模拟2048游戏 原题&#xff1a; 题目描述 此时&#xff0c;Conan却在一旁玩着2048。 这是一个4*4的矩阵&#xff0c;初始全为0。每次一个没有数字的格子中会随机出现一个2或4&#xff0c;每次可以选择上下左右其中一个方向去滑动&#xff0c;每…

在Docker中部署Asp.net core2.1以及修改发布

本篇文章主要是如何在Docker容器中运行ASP.NET Core应用程序&#xff0c;以及修改系统之后&#xff0c;发布更新。本文章采用自定义的Docker文件系统要求&#xff1a;1.服务器或本地已经安装docker一、创建一个Asp.Net Core 2.1 Web应用&#xff08;若可以熟练创建项目&#xf…

HDU5322 - cdq分治FFT加速dp

5322 Hope [CDQ分治FFT加速计算dp] 题意 每一个每一个排列,排列中每个数向它后面第一个比它大的数连一条边. 每个排列对于答案的贡献是这个排列所生成的图中的每一个联通量中点的个数的平方之积. 例如:排列 1,2,3,6,4,51,2,3,6,4,51,2,3,6,4,5 其中 1,2,3,61,2,3,61,2,3,6形…

AT2300-[ARC068C]Snuke Line【整除分块】

正题 题目链接: https://www.luogu.com.cn/problem/AT2300 https://atcoder.jp/contests/arc068/tasks/arc068_c 题目大意 有mmm个车站&#xff0c;nnn种礼品&#xff0c;第iii种可以在[li,ri][l_i,r_i][li​,ri​]的车站买到&#xff0c;第ddd辆车会近过编号为ddd的倍数的车…

【二分】游戏

游戏 题目大意&#xff1a; 有三个套餐&#xff0c;1&#xff1a;一个a、一个b和一个c,2&#xff1a;一个a和两个b&#xff0c;3&#xff1a;两个a和一个b&#xff0c;现在有一定的a、b和c&#xff0c;要使任意两个形同的套餐不相邻&#xff0c;问最多可以有多少个套餐&#…

要用Identity Server 4 -- OAuth 2.0 超级简介

OAuth 2.0 简介OAuth有一些定义:OAuth 2.0是一个委托协议, 它可以让那些控制资源的人允许某个应用以代表他们来访问他们控制的资源, 注意是代表这些人, 而不是假冒或模仿这些人. 这个应用从资源的所有者那里获得到授权(Authorization)和access token, 随后就可以使用这个access…

清明梦超能力者黄YY[树链剖分+扫描线,线段树合并]

清明梦超能力者黄YY 题目连接 https://www.nowcoder.com/acm/contest/206/I 暂时有两种做法. 算法一 涉及:树链剖分,扫描线 在一个线段的情况下,我们可以把一个染色区间拆成左端点处增加事件,右端点处删除事件. 维护一颗权值线段树. 这样,端点从小到大扫描时,遇到增加事件…