cf里的一些简单组合数题
cf711D 成环的和不成环的要单独计算,环用双联通做的QAQ
/*
所有情况-成环的情况
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
#define mod 1000000007
#define ll long long
struct Edge{int to,nxt;}edge[maxn<<];
int n,head[maxn],tot;
ll ans;
void init(){
memset(head,-,sizeof head);
tot=;
}
void addedge(int u,int v){
edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
ll Pow(ll a,ll b){
ll res=;
while(b){
if(b%)res=(res*a)%mod;
b>>=;a=a*a%mod;
}
return res;
} int dfn[maxn],low[maxn],ind,bridge[maxn<<];
void tarjan(int x,int in_edge){
dfn[x]=low[x]=++ind;
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(!dfn[y]){
tarjan(y,i);
low[x]=min(low[x],low[y]);
if(low[x]<low[y])bridge[i]=bridge[i^]=;
}
else if(i!=(in_edge^))
low[x]=min(low[x],dfn[y]);
} }
int c[maxn],size[maxn],dcc;
void dfs(int u){
c[u]=dcc;size[dcc]++;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(c[v]||bridge[i])continue;
dfs(v);
}
} int main(){
init();
ans=;
cin>>n;
int v,cnt=;
for(int u=;u<=n;u++){
cin>>v;
addedge(u,v);addedge(v,u);
}
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i,); //染色
for(int i=;i<=n;i++)
if(!c[i]){++dcc;dfs(i);} for(int i=;i<=dcc;i++){
if(size[i]==)cnt++;
else ans=ans*(Pow(,size[i])-)%mod;
} ans=ans*Pow(,cnt)%mod;
cout<<ans;
return ;
}
cf340B 开始推公式了
/*
数组a组成的全排列
求差值之和
显然|ai-aj|出现的次数是(n-1)!次
那么答案就是sum|si-sj| / n
怎么求sum|si-sj|?
排个序,然后用前缀和求即可
8-4+2+1+2+3=4+8=12+12
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 200005
ll tot,n,a[maxn],sum[maxn]; int main(){
cin>>n;
for(int i=;i<=n;i++)cin>>a[i];
sort(a+,a++n);
for(int i=;i<=n;i++)sum[i]=sum[i-]+a[i];
for(int i=;i<=n;i++){
tot+=sum[n]-sum[i]-a[i]*(n-i);
tot+=a[i]*(i-)-sum[i-];
}
//tot*=2;
tot+=sum[n];
ll d=__gcd(n,tot);
cout<<tot/d<<" "<<n/d<<endl;
}
cf500D开始在树上推公式了,要注意最后用double。。ll不知道为什么会炸。。。
/*
找出所有路径然后求平均值
就是sum|(d(a,b)+d(b,c))*2|/C(n,3)
如何求sum,
边<u,v>的贡献次数是
cnt=C(size[u],2)*C(n-size[u]-1,1)+C(size[u],1)*C(n-size[u]-1,2)
其贡献是cnt*2*w
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
#define ll long long
struct Edge{int to,nxt;}edge[maxn<<];
struct E{int u,v,w;}e[maxn];
int head[maxn],tot,n;
double F;
void init(){
memset(head,-,sizeof head);
tot=;
F=;
F=((double)n*(n-)*(n-))/;
}
void addedge(int u,int v){
edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
ll size[maxn];
void dfs(int u,int pre){
size[u]=;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(v==pre)continue;
dfs(v,u);size[u]+=size[v];
}
}
ll cnt[maxn];
ll C(ll a,ll b){
if(a<b)return ;
if(b==)return a;
if(b==)return (ll)a*(a-)/;
}
int main(){ cin>>n; init();
for(int i=;i<n;i++){
cin>>e[i].u>>e[i].v>>e[i].w;
addedge(e[i].u,e[i].v);
addedge(e[i].v,e[i].u);
}
dfs(,);
for(int i=;i<n;i++){
int u=e[i].u,v=e[i].v;
if(size[u]>size[v])swap(u,v);
cnt[i]=(ll)C(size[u],)*C(n-size[u],)+(ll)C(size[u],)*C(n-size[u],);
}
double sum=;
for(int i=;i<n;i++)
sum+=(double)cnt[i]**e[i].w;
//cout<<sum; int q;
cin>>q;
while(q--){
int id,w;
cin>>id>>w;
sum+=(double)(-(cnt[id]**e[id].w)+(cnt[id]**w));
e[id].w=w;
printf("%lf\n",sum/F);
}
}
cf150B 又是回文串拆分成奇偶串的题。。需要特判一些情况
/*
若k==n,那么就是可以组成的回文的个数 m^(n/2)
k=1或k是偶数:全等
k是奇数:分奇偶串后全等即可
*/
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long
ll n,m,k;
ll Pow(ll a,ll b){
ll c=;
while(b){
if(b%)c=c*a%mod;
b>>=;a=a*a%mod;
}
return c;
}
int main(){
cin>>n>>m>>k;
if(k== || k>n){
cout<<(ll)Pow(m,n);
return ;
}
if(k<n){
if(k%==){
cout<<m;
return ;
}
cout<<(ll)m*m;
return ;
}
cout<<(ll)Pow(m,(n-)/+);
return ;
}
cf626D 好题!求c1+c2<c3的对数,由于数值较小,所以开个桶完美解决!
/*
显然有C(n,2)中选球组合
我们另第i中选球组合选出的求权值为(ai,bi)
那么选三次后要使得第二个人的总权值大于第一个人
即a1+a2+b3<b1+b2+a3
即(a1-b1)+(a2-b2)<(a3-b3)
我们另ai-bi=ci,变成求使c1+c2<c3成立的对数
如何求c1+c2<c3的对数,直接对c求是不可能了,复杂度似乎是o(n4)。。 、
可以开个桶+前缀和进行求解复杂度降到O(5000*5000)
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 5005
#define ll long long
ll n,a[maxn],cnt[maxn],sum[maxn<<];
int main(){
double F=;
cin>>n;
F=n*(n-)/;F=F*F*F;
for(int i=;i<=n;i++)cin>>a[i];
for(int i=;i<n;i++)
for(int j=i+;j<=n;j++)
cnt[abs(a[i]-a[j])]++;
for(int i=;i<=;i++){
if(cnt[i]==)continue;
for(int j=;j<=;j++)
sum[i+j]+=cnt[i]*cnt[j];
}
for(int i=;i<=;i++)
sum[i]=sum[i-]+sum[i];
double tot=;
for(int i=;i<=;i++)
tot+=(double)cnt[i]*sum[i-];
printf("%.10lf",tot/F);
return ;
}
cf272D 难点在于m不是个质数,不用逆元的话要用别的办法转化一下消去2即可
/*
统计每列的点数量
用乘法原理处理列间即可,
注意还要除以每列中相同的点的情况
因为一列中完全相同的点最多是2
2x=1(%m)
*/
#include<bits/stdc++.h>
#include<map>
using namespace std;
#define maxn 200005
#define ll long long
ll n,a[maxn],b[maxn];
map<ll,ll> s,cnt;
map<ll,ll>::iterator it;
ll m,ans,inv;
ll f[maxn];
void init(){
f[]=f[]=;
for(int i=;i<=;i++)f[i]=(ll)f[i-]*i%m;
} int main(){
cnt.clear();s.clear();
cin>>n;
for(int i=;i<=n;i++)cin>>a[i];
for(int i=;i<=n;i++)cin>>b[i];
cin>>m;init(); for(int i=;i<=n;i++){
if(a[i]==b[i])s[a[i]]++;
cnt[a[i]]++,cnt[b[i]]++;
} ll ans=;
for(it=cnt.begin();it!=cnt.end();it++){
ll c=(*it).first;
ans=ans*f[cnt[c]-s[c]*]%m;
ll t=cnt[c]-s[c]*;
if(s[c])
for(int i=;i<=s[c];i++){
t+=;ans=ans*((t*(t-))/%m)%m;
}
}
cout<<ans;
}
cf里的一些简单组合数题的更多相关文章
- 2019浙大校赛--A--Thanks, TuSimple!(简单模拟题)
这题前三段都是一堆吹爆赞助商的屁话,正式题目在图片下边,一个简单模拟题. 题目大意: 有n个男生,m个女生在进行舞会,其中一部分男生祥和比自己矮的女生跳舞,一部分男生想和比自己高的女生跳舞,一部分女生 ...
- java算法题每日一练01,java入门简单算法题小练
1.给数组做反序 public class Ak01 { public static void main(String[] args) { int[] a = new int[]{22,48,41,2 ...
- 简单数据结构题(from 钟子谦——IOI2018集训队自选题)
简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...
- CF上的3道小题(2)
CF上的3道小题(2) T1:CF630K Indivisibility 题意:给出一个数n,求1到n的数中不能被2到9中任意一个数整除的数. 分析:容斥一下,没了. 代码: #include < ...
- CF上的3道小题(1)
CF上的3道小题 终于调完了啊.... T1:CF702E Analysis of Pathes in Functional Graph 题意:你获得了一个n个点有向图,每个点只有一条出边.第i个点的 ...
- 清橙A1206.小Z的袜子 && CF 86D(莫队两题)
清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...
- Light oj-1100 - Again Array Queries,又是这个题,上次那个题用的线段树,这题差点就陷坑里了,简单的抽屉原理加暴力就可以了,真是坑~~
1100 - Again Array Queries ...
- CF 322A Ciel and Dancing 好简单的题。。最喜欢水题了
A. Ciel and Dancing time limit per test 1 second memory limit per test 256 megabytes input standard ...
- 一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)
首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自 ...
随机推荐
- 表单相关标签之form标签
表单能够包含 input 元素,比如文本字段.复选框.单选框.提交按钮等等. 表单还可以包含 menus.textarea.fieldset.legend 和 label 元素以及其它块级元素 表单用 ...
- 2018JAVA面试题附答案
JAVA基础 JAVA中的几种基本类型,各占用多少字节? String能被继承吗?为什么? 不可以,因为String类有final修饰符,而final不能被继承的,实现细节不允许改变.平常我们定义的S ...
- nutz学习笔记(1)
写在前头 最近到了合肥分公司,分公司用的架构为nutz·····目前在根据官方文档(http://nutzam.com/core/nutz_preface.html)自学并实践中,此笔记将不会如官方文 ...
- Zookeeper学习笔记4
开源客户端 ZkClient <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...
- SpringBoot2.0+ DataSourceInitializer不生效的问题
1.在url后声明时区 2.更换mysql6.0+的驱动 3.配置属性initialization-mode 为 always 我就是这样解决问题的,如果没解决的话,请在留言处指出错误.谢谢
- delphi 的插件机制与自动更新
delphi 的插件机制与自动更新 : 1.https://download.csdn.net/download/cxp_2008/2226978 参考 2.https://download.cs ...
- requests库入门09-OAUTH认证
实际登陆中,认证用到的token会变的,不过可以在GIthub设置一个私人token. 如图,登录GIthub,然后用户下面选择Settings/Developer settings/Personal ...
- UDP可靠传输那些事
有空来论坛走走,发现讨论udp可靠传输又热了起来,有人认为udp高效率,有人认为udp丢包重传机制容易控制,还有朋友搞极限测试,当然也有人推销自己的东西,这里写一点我个人的看法. udp可靠传输其实非 ...
- Mudo C++网络库第二章学习笔记
线程同步的精要 并发有两种基本的模型: 一种是message passing(消息传递); 另一种是shared memory(共享内存); 在分布式系统中(有多台物理机需要通信), 运行在多台机器上 ...
- csrfguard3.1 部署笔记
1:git clone 导入csrfguard 2:点击菜单栏View->Tool Windows->Maven projects 3:Lifecycle clean build 4:t ...