作业

poj 1091 跳蚤

容斥原理。

考虑能否跳到旁边就是卡牌的\(gcd\)是否是1,可以根据裴蜀定理证明。

考虑正着做十分的麻烦,所以倒着做,也就是用\(M^N - (不合法)\)即可。

不合法显然就是\(gcd\)不为1的情况,那么我们考虑枚举\(gcd\),\((1 \leq gcd \leq 15)\),第\(n + 1\)个数一直是\(m\)所以不用理它。

考虑每个\(gcd\)的贡献,如果所有的都能被整除,那么产生的方案数就是:

\(({m \over gcd})^n\)

表示在小于等于\(m\)的数中有多少能够被当前的\(gcd\)整除,那么每个位置就有这么多数字可以选择,就转化成了容斥原理的问题了,\(dfs\)枚举\(m\)的质因数统计即可。

#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
#define int long long
int n,m;
const int MAXN = 1e5 + 10;
int Ans;
int p[MAXN];
int ans;
int div (int now) {
int res = 0;
for(int i = 2;i * i <= now; ++i) {
if(now % i == 0) {
p[++res] = i;
now /= i;
while(now % i == 0) now /= i;
}
}
if(now > 1) p[++res] = now;
return res;
} int pow_mod(int a,int b) {
int res = 1;
while(b) {
if(b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
} void dfs(int num,int y,int now) {
if(now > m) return;
if(num == ans + 1) {
if(y) {
if(y & 1) {
Ans -= pow_mod(m / now,n);
}
else {
Ans += pow_mod(m / now,n);
}
}
return;
}
dfs(num + 1,y,now);
dfs(num + 1,y + 1,now * p[num]);
} signed main () {
cin >> n >> m;
Ans = pow_mod(m,n);
//cout<<Ans<<endl;
ans = div(m);
//cout<<ans<<endl;
dfs(1,0,1);
cout<<Ans<<endl;
return 0;
}

ps:这题为啥不用取模?真是让人难以琢磨。

hdu 5121 just a mistake

期望\(dp\)+容斥原理

题目大意就是让你随机构造一个排列,然后判断是否与集合中的点有连边然后一个一个的连接。

乍一看十分难做,第二眼还是十分难做,做了\(1h23min\)。。。

首先考虑如何统计贡献,一般的方程就是如果第\(i\)是\(p_i\)的时候,某些贡献是多少,由于这个问题拓展到了树上,那么就是设\(f_{i,j}\)表示以\(i\)为根的子树中,\(i\)排在第\(j\)位且必须选的方案数。

那么子树中的点如果排在\(i\) 的前面就不能选,因为\(i\)必选,贡献就得减去它。

如果在后面,选了\(i\)之后也不能选它,然后组合数统计答案即可。

具体就是以每个点为根去做搜索,统计出答案之后相加即可,由于期望的线性性。

再来说说具体怎么计算答案,枚举\(y\)这棵子树的1到siz[y]的集合中前\(k\)个插入到\(i\)前面,后面的插在后面,乘上\(f_{i,j}\),在乘上选位置的方案数。

选位置的方案数就是\(C_{n + m}^{n}\)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
const int MAXN = 210;
int C[MAXN][MAXN];
int siz[MAXN];
int f[MAXN][MAXN];
int lnk[MAXN];
int fac[MAXN];
const int mod = 1e9 + 7;
int cnt;
int head[MAXN << 1];
void pre() {
memset(C,0,sizeof C);
memset(fac,0,sizeof fac);
C[0][0] = 1;
fac[0] = 1;
for(int i = 1;i <= 200; ++i) {
C[i][0] = C[i][i] = 1;
fac[i] = (fac[i - 1] * i) % mod;
for(int j = 1;j <= i; ++j) {
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
}
}
return;
}
int T,n,x,y;
int ans;
struct edge {
int to;
int nxt;
}e[MAXN << 1];
void add(int u,int v) {
e[++cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
return;
} void Add(int u,int v) {
add(u,v);
add(v,u);
} void dfs(int x,int fa) {
f[x][0] = 0;f[x][1] = 1;
siz[x] = 1;
for(int i = head[x];i;i=e[i].nxt) {
int y = e[i].to;
if(y == fa) continue;
dfs(y,x);
int all_state = fac[siz[y]];
int tmp = siz[y];
int sum_state = siz[x] + siz[y];
siz[x] += siz[y];
memset(lnk,0,sizeof lnk);
for(int j = 0;j <= siz[y]; ++j,--tmp) {
all_state = (all_state + mod - f[y][j]) % mod;
for(int k = 1;k <= sum_state - siz[y]; ++k) {
lnk[j + k] = ((lnk[j + k] + all_state * f[x][k] % mod * C[j + k - 1][j] % mod * C[sum_state - j - k][tmp] % mod) % mod + mod) % mod;
}
}
for(int j = 0;j <= sum_state; ++j) {
f[x][j] = lnk[j];
}
}
}
int cas;
signed main () {
scanf("%lld",&T);
pre();
while(T--) {
scanf("%lld",&n);
memset(head,0,sizeof head);
cnt = 0;
memset(f,0,sizeof f);
memset(lnk,0,sizeof lnk);
memset(siz,0,sizeof siz);
for(int i = 1;i < n; ++i) {
scanf("%lld %lld",&x,&y);
Add(x,y);
}
ans = 0;
for(int i = 1;i <= n; ++i) {
memset(f,0,sizeof f);
dfs(i,0);
for(int j = 1;j <= n; ++j) {
ans = (ans + f[i][j]) % mod;
}
}
printf("Case #%lld: %lld\n",++cas,ans);
}
return 0;
}

ps:组合数没取模调了半天没看出来。。。

hdu 4336 Card Collector

裸.容斥原理

一坨式子懒得写了.

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define db double
int n,tmp;
db p[21];
db ans;
db sum;
void dfs(int now,db P,int st) {
if(now == tmp) {
ans += 1.0 / P;
return;
}
for(int i = st;i <= n; ++i) {
dfs(now + 1,P + p[i],i + 1);
}
}
int main () {
while(~scanf("%d",&n)) {
sum = 0;
for(int i = 1;i <= n; ++i) {
scanf("%lf",&p[i]);
sum += 1.0 / p[i];
}
for(int i = 2;i <= n; ++i) {
tmp = i;
ans = 0;
dfs(0,0,1);
//cout<<ans<<endl;
if((i & 1) == 0) {
ans = -ans;
}
sum += ans;
}
printf("%.6lf\n",sum);
}
return 0;
}

hdu 6314

容斥原理。

挖挫...这题真的是卡常数??

首先至少这种问题在高中就学过用补集去算,设\(f_{n,m}\)表示没有任何一行一列有全是黑色。

简单推一下这个就是:

\(f_{n,m} = \sum_{i = 0}^{n} \sum_{j = 0}^{m} C_{n}^{i} \times C_{m}^{j} \times (-1)^{i + j} \times 2^{(n - i) \times (m - j)}\)

答案首先就是:

\(Ans = \sum_{i = 0}^{n - A} \sum_{j = 0}^{m - B} C_{n}^{i} \times C_{m}^{j} \times f_{i,j}\)

\(\;\;\;\;\;\;\;= \sum_{i = 0}^{n - A} \sum_{j = 0}^{m - B} C_{n}^{i} \times C_{m}^{j} \sum_{u = 0}^{i} \sum_{v = 0}^{j} C_{i}^{u} \times C_{j}^{v} \times (-1)^{u + v} \times 2^{(i - u) \times (j - v)}\)

考虑哪些是可以直接处理出来的,例如这个:

\(\sum \sum C_{n}^{i} \times C_{m}^{j}\)

就可以直接算一手...

考虑后面的怎么算?

组合数展开就行了,预处理出形如\(i + j = k\)并且\(i\)的值大于等于\(l\) 的和,然后处理\(g_{i,j} = {2^{i \times j} \over i! \times j!}\)

枚举\(u,v\)即可。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
#define int long long
const int mod = 998244353;
const int MAXN = 3010;
int C[MAXN][MAXN];
int g[MAXN][MAXN];
int fac[MAXN];
int inv[MAXN];
int n,m,A,B;int ans;
int two[MAXN * MAXN];
int pow_mod(int a,int b) {
int res = 1;
while(b) {
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void pre() {
fac[0] = 1;
inv[0] = 1;
two[0] = 1;
for(int i = 1;i <= MAXN * MAXN; ++i) {
two[i] = two[i - 1] * 2 % mod;
}
for(int i = 1;i <= MAXN; ++i) {
fac[i] = fac[i - 1] * i % mod;
inv[i] = pow_mod(fac[i],mod - 2);
}
for(int i = 0;i <= 3000; ++i) {
for(int j = i;j >= 0; --j) {
C[i][j] = (((i - j) & 1 ? (mod - (inv[j] * inv[i - j] % mod)) : (inv[j] * inv[i - j] % mod)) + C[i][j + 1]) % mod;
//cout<<C[i][j]<<endl;
}
}
for(int i = 0;i <= 3000; ++i) {
for(int j = 0;j <= 3000; ++j) {
g[i][j] = two[i * j] * inv[i] % mod * inv[j] % mod;
//if(j <= 30 and i == 0) cout<<g[i][j]<<endl;
}
}
}
int cnt = 0;
//i == 1 and j == 1
signed main () {
pre();
while(~scanf("%d %d %d %d",&n,&m,&A,&B)) {
ans = 0;
for(int i = 0;i <= n - A; ++i) {
for(int j = 0;j <= m - B; ++j) {
ans = ((ans + C[n - i][A] * C[m - j][B] % mod * g[i][j] % mod) % mod + mod) % mod;
//cout<<ans<<endl;
}
}
//n : 3 m : 4 A : 1 B : 2
//cout<<g[1][1]<<endl;
//cout<<two[1]<<' '<<inv[1]<<' '<<inv[1]<<endl;
//cout<<C[2][1]<<' '<<C[3][2]<<endl;
ans = ans * fac[n] % mod * fac[m] % mod;
ans = (ans % mod + mod) % mod;
cout<<ans<<endl;
}
return 0;
}

ps:处理\(two\)数组的时候我居然乘的是2...

但是...\(AC\)不了...

卡常!

卡了三点常就过了:

  • 去掉#define int long long改为1ll * ...去算
  • int变为register int
  • 函数前面加上inline

然后呢?就过了。。。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
#define rint register int
const int mod = 998244353;
const int MAXN = 3010;
int C[MAXN][MAXN];
int g[MAXN][MAXN];
int fac[MAXN];
int inv[MAXN];
int n,m,A,B;int ans;
int two[MAXN * MAXN];
inline int pow_mod(int a,int b) {
int res = 1;
while(b) {
if(b & 1) res = 1ll * res * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
}
return res;
}
inline void pre() {
fac[0] = 1;
inv[0] = 1;
two[0] = 1;
for(rint i = 1;i <= MAXN * MAXN; ++i) {
two[i] = two[i - 1] * 2 % mod;
}
for(rint i = 1;i <= MAXN; ++i) {
fac[i] = 1ll * fac[i - 1] * i % mod;
inv[i] = pow_mod(fac[i],mod - 2);
}
for(rint i = 0;i <= 3000; ++i) {
for(rint j = i;j >= 0; --j) {
C[i][j] = (((i - j) & 1 ? (mod - (1ll * inv[j] * inv[i - j] % mod)) : (1ll * inv[j] * inv[i - j] % mod)) + C[i][j + 1]) % mod;
//cout<<C[i][j]<<endl;
}
}
for(rint i = 0;i <= 3000; ++i) {
for(rint j = 0;j <= 3000; ++j) {
g[i][j] = 1ll * two[i * j] * inv[i] % mod * inv[j] % mod;
//if(j <= 30 and i == 0) cout<<g[i][j]<<endl;
}
}
}
int cnt = 0;
//i == 1 and j == 1
signed main () {
pre();
while(~scanf("%d %d %d %d",&n,&m,&A,&B)) {
ans = 0;
for(rint i = 0;i <= n - A; ++i) {
for(rint j = 0;j <= m - B; ++j) {
ans = ((ans + 1ll * C[n - i][A] * C[m - j][B] % mod * 1ll * g[i][j] % mod) % mod + mod) % mod;
//cout<<ans<<endl;
}
}
//n : 3 m : 4 A : 1 B : 2
//cout<<g[1][1]<<endl;
//cout<<two[1]<<' '<<inv[1]<<' '<<inv[1]<<endl;
//cout<<C[2][1]<<' '<<C[3][2]<<endl;
ans = ans * 1ll * fac[n] % mod * fac[m] % mod;
ans = (ans % mod + mod) % mod;
printf("%d\n",ans);
}
return 0;
}

hdu 5838

状压+容斥

#include <bits/stdc++.h>
using namespace std;
#define int long long
//const int mod = 772002;
const int mod = 12345678;
int cnt;
int n,m;
int cas;
int ans;
int dx[8] = {1,-1,0,0,1,-1,1,-1};
int dy[8] = {0,0,1,-1,1,1,-1,-1};
int nx[10];
int ny[10];
int f[30][1 << 10];
int sta[1 << 10];
char s[7][7];
int vis[7][7]; int ok(int x,int y) {
return x >= 0 && x < n && y >= 0 && y < m;
} int dp() {
cnt = 0;
for(int i = 0;i < n; ++i) {
for(int j = 0;j < m; ++j) {
if(s[i][j] == 'X') {
nx[cnt] = i;
ny[cnt++] = j;
}
}
}
memset(sta,0,sizeof sta);
for(int i = 0;i < (1 << cnt); ++i) {
memset(vis,0,sizeof vis);
for(int j = 0;j < cnt; ++j) {
if(~i & (1 << j)) {
for(int k = 0;k < 8; ++k) {
int Nx = nx[j] + dx[k];
int Ny = ny[j] + dy[k];
if(!ok(Nx,Ny)) continue;
vis[Nx][Ny] = 1;
}
vis[nx[j]][ny[j]] = 1;
}
} for(int j = 0;j < n; ++j) {
for(int k = 0;k < m; ++k) {
if(!vis[j][k]) {
sta[i] ++;
}
}
}
}
int all_sta = n * m;
memset(f,0,sizeof f);
f[0][0] = 1;
for(int i = 1; i <= all_sta; ++i) {
for(int j = 0;j < (1 << cnt); ++j) {
for(int k = 0;k < cnt; ++k) {
if(j & (1 << k)) {
f[i][j] = (f[i][j] + f[i - 1][j ^ (1 << k)]) % mod;
}
}
f[i][j] = ((f[i][j] + 1ll * f[i - 1][j] * max(0ll,1ll * sta[j] - i + 1) % mod) % mod + mod) % mod;
}
}
return f[all_sta][(1 << cnt) - 1];
} void dfs(int now,int lim,int f) {
if(lim == m) {
ans = ((ans + 1ll * dp() * f % mod) % mod + mod) % mod;
return;
}
else if(now == n) {
dfs(0,lim + 1,f);
return;
}
else {
dfs(now + 1,lim,f);
}
if(s[now][lim] != 'X') {
for(int j = 0;j < 8; ++j) {
int new_x = now + dx[j];
int new_y = lim + dy[j];
if(ok(new_x,new_y) && s[new_x][new_y] == 'X') goto state;
}
s[now][lim] = 'X';
dfs(now + 1,lim,-f);
s[now][lim] = '.';
state : ;
}
}
signed main () {
while(~scanf("%lld %lld",&n,&m)) {
ans = 0;
for(int i = 0;i < n; ++i) {
scanf("%s",s[i]);
}
dfs(0,0,1);
//cout<<"Case #"<<(++cas)<<':'<<' '<<(((ans % mod + mod) % mod) == m ? 0 : ((ans % mod + mod) % mod))<<endl;
cout<<((ans % mod + mod) % mod)<<endl;
}
return 0;
}
/*
2 4
.X..
...X
4 2
X.
..
..
X.
1 2
XX
*/ /*
Case #1: 2100
Case #2: 2520
Case #3: 0
*/

ZROI week3的更多相关文章

  1. 个人作业-Week3

    个人作业-Week3 1. 软件工程师的成长 同学们在上这门课的时候,还是大三,你的困难和迷茫,别人一定有过.请看看别人怎么学习的,有些是科班,有些是野路子,有些成功,有些失败. 请读完下面所有博客( ...

  2. Spark小课堂Week3 FirstSparkApp(Dataframe开发)

    Spark小课堂Week3 FirstSparkApp(代码优化) RDD代码简化 对于昨天练习的代码,我们可以从几个方面来简化: 使用fluent风格写法,可以减少对于中间变量的定义. 使用lamb ...

  3. Spark小课堂Week3 FirstSparkApp(RDD开发)

    Spark小课堂Week3 FirstSparkApp 问题:Java有哪些数据结构 大致有如下几种,其中List与Map是最重要的: List Map Set Array Heap Stack Qu ...

  4. Deep Learning--week1~week3

    week1 一张图片,设像素为64*64, 颜色通道为红蓝绿三通道,则对应3个64*64实数矩阵 为了用向量表示这些矩阵,将这些矩阵的像素值展开为一个向量x作为算法的输入 从红色到绿色再到蓝色,依次按 ...

  5. 20165214 2018-2019-2 《网络对抗技术》Exp1 PC平台逆向破解 Week3

    <网络对抗技术>Exp1 PC平台逆向破解之"逆向及Bof基础实践说明" Week3 一. 实验预习 1.什么是漏洞?漏洞有什么危害? 漏洞就是在计算机硬件.软件.协议 ...

  6. 个人作业Week3

    个人作业week3 一.  调研,评测 1.我的使用体验 版本:IOS版   BUG_1: 点击单词本中的“同步”后,会提示登录Microsoft账户.登录成功立即开始同步单词本.在单词本同步过程中, ...

  7. Week3 关于“微软必应词典客户端”的案例分析

    第一部分  调研,评测 一.iphone客户端的bug挖掘: 1.在例句中点击单词或短语,如果这个时候点得稍微快了一点,关联相应的翻译时会出现混乱. 经过调查发现,这个bug应该是必应得一个全平台错误 ...

  8. [BUAA_SE_2017]案例分析-Week3

    Week3 案例分析 一.调研评测 案例: 神策数据的数据概览功能 Demo: 电商类产品Demo 评价: d) 好,不错 个人评价:神策数据电商类产品Demo的数据概览功能是相当不错的.首先点击进入 ...

  9. 20165310 NstSec2019 Week3 Exp1 逆向与Bof基础

    20165310 NstSec2019 Week3 Exp1 逆向与Bof基础 一.实验内容 实验目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用fo ...

随机推荐

  1. 关于设置shadowPath的重要性

    这是超级容易添加阴影到iOS中的任何视图.所有您需要做的是 添加QuartzCore框架到项目中(如果不存在的话) 导入QuartzCore到您的执行文件 添加一行如[myView.layer set ...

  2. css3D动画

    css3D动画 前言 最近玩了玩用css来构建3D效果,写了几个demo,所以博客总结一下. 在阅读这篇博客之前,请先自行了解一下css 3D的属性,例如:transform-style,transf ...

  3. maven创建的quickstart项目生成可执行jar

    maven创建的quickstart项目在打包成jar后,通过Java -jar 文件名.jar 会提示没有主清单属性. 为了生成可执行的jar,需要添加maven插件 maven-shade-plu ...

  4. Docker容器数据卷volumes-from

    定义4个终端: 终端host终端container dc01终端container dc02终端container dc03各个容器之间的关系: 1.启动一个父容器dc01启动一个父容器dc01,并在 ...

  5. Python 进阶_OOP 面向对象编程_self 的实例绑定

    目录 目录 self 和绑定 调用非绑定的方法 self 和绑定 在 Python 中 self 变量是特殊的, 其用于在实例方法中引用该方法所绑定的实例, 换句话说就是 Python 在实例化对象时 ...

  6. 测开之路四十七:Django之请求静态资源与模板

    框架必要的配置 import sysfrom django.conf.urls import urlfrom django.conf import settingsfrom django.http i ...

  7. Python异或加密字符串

    import os import sys import struct def enc(path, key): path_ret = "" for i in range(0, len ...

  8. C++中继承的protected访问级别

    1,子类是否可以直接访问父类的私有成员? 2,根据面向对象理论: 根据 C++ 语法: 3,继承中的访问级别编程实验: #include <iostream> #include <s ...

  9. [fw]GDT是在分段中為了相容real mode 跟 protected mode的產物

    在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table). 为什么要有GDT?我们首先考虑一下在Real Mode下的编程模型: 在R ...

  10. 一个简化的插件框架c#

    利用MEF实现插件加载. 定义了一套接口,分别实现插件主界面,插件,业务插件等. 整套加载完全使用MEF2. 所有插件分开,包括主界面也是插件实现. 用一个应用程序,只有Main和插件加载方法.我管它 ...