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网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自 ...
随机推荐
- WSGI、uwsgi和uWSGI
一.WSGI WSGI ( Web Server Gateway Interface )是一个网络服务器和网络应用的通用接口的规范或者用于Python框架. 由于python开发人员在网络框架的选择限 ...
- 列出下面几项的URL并解释每部分代表的含义
列出下面几项的URL并解释每部分代表的含义 a.你的学校 b.你的学校的计算机科学系 c.你的老师的主页
- ubuntu14.04升级mysql5.5至mysql5.7
原文链接:https://www.cnblogs.com/os-python/p/6842485.html 1.下载mysql-apt的配置包,并安装 wget https://dev.mysql.c ...
- 阿里云ECS CentOS 7 安装图形化桌面
CentOS 7 系统下,本文以 MATE 桌面环境安装进行安装配置说明: 1 . 安装 X Window System. yum groups install "X Window Syst ...
- codevs 1081 线段树练习2 (线段树)
题目: 题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下 ...
- 利用微信企业号的告警功能,联动检测ICMP的shell脚本
作者:邓聪聪 由于设备IP众多,为了及时发现IP地址有不可达现象,利用微信的联动报警,及时发现问题,以下是脚本内容!!! ping.sh #!/bin/bash ###SCRIPT_NAME:icmp ...
- u3d 2D开发学习
http://gad.qq.com/article/detail/45365 https://blog.csdn.net/s556699/article/details/55224830 UI层设计 ...
- python装饰器的4种类型:函数装饰函数、函数装饰类、类装饰函数、类装饰类
一:函数装饰函数 def wrapFun(func): def inner(a, b): print('function name:', func.__name__) r = func(a, b) r ...
- 浏览器开启桌面通知Web Notification
本文主要描述如何开启各个浏览器的桌面通知功能 一.谷歌浏览器(chrome) 点击地址栏前面的图标
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path 解决办法
♦ 未在 Java构建路径中 找到父类 "javax.servlet.http.HttpServlet" ♦ 解决办法: 项目右击 → Build Path → 右侧 Add L ...