期望得分:100+60+0=160

实际得分:100+30+0=130

考场上用的哈希

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mod 1000003
#define mod2 100003
char s[];
bool vis[mod],vis2[mod2];
int hash1,hash2;
int gethash()
{
int len=strlen(s);
sort(s,s+len);
hash1=s[]-'A'+,hash2=hash1;
for(int i=;i<len;i++)
{
hash1=(hash1*+(s[i]-'A')+)%mod;
hash2=(hash2*+(s[i]-'A')+)%mod2;
}
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int n,ans=;
scanf("%d",&n);
while(n--)
{
scanf("%s",s);
gethash();
if(!vis[hash1] || !vis2[hash2]) vis[hash1]=true,vis2[hash2]=true,ans++;
}
printf("%d",ans);
}

myself

std直接sort,map 判重结构体

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map> using namespace std; struct node
{
int z[];
node()
{
memset(z,,sizeof(z));
}
bool operator<(const node &a)const
{
for (int b=;b<=;b++)
if (z[b]!=a.z[b]) return z[b]<a.z[b];
return false;
}
}now; map<node,bool> use; int ans,n; char s[]; int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
for (int a=;a<=n;a++)
{
scanf("%s",s+);
int l=strlen(s+);
memset(now.z,,sizeof(now.z));
for (int a=;a<=l;a++)
now.z[s[a]-'A'+]++;
if (!use[now]) use[now]=true,ans++;
}
printf("%d\n",ans); return ;
}

std

设分成的每段长为Li,g=gcd(Li)

那么一共有n/g 个单位

设f[g]表示以g为周长,且三边gcd为1 的三角形的个数

设h[n/g]表示把n/g个单位 分配给任意多个三角形的个数

那么 ans=Σ f[g]*h[n/g]   (g|n)

求f[g]:

设g=a+b+c,且a<=b<=c

对b和c的大小分两种情况讨论:

① b==c :

==> g=a+2b,那么b∈[ceil(g/3),floor((g-1)/2)]

所以f[g]=floor((g-1)/2)- ceil(g/3) +1

② b<c :

a,b,c 的每一种方案都可以看做由 a,b,c-1的每一种方案转移过来

但有一种除外:a+b=c,因为此时a,b,c-1 合法,a,b,c 不合法

当g为偶数时,a+b+a+b=g,g=2*(a+b),所以有floor(g/4)个

所以f[g]=f[g-1]+ (b&1)? 0 : -g/4

然后因为要求三边长互质,所以枚举g的每个因数k,f[g]-=f[k]

求h[i]:

把i个物品分成任意份的方案数=C(i-1,0)+C(i-1,1)+……+C(i-1,i-1)

= 2^(i-1)

#include<cmath>
#include<cstdio>
#include<algorithm> #define N 1000001
const int mod=1e9+; using namespace std; int f[N],g[N];
int divisor[N],cnt; void ADD(int &a,int b) { a+=b; a>=mod ? a-=mod : ; } int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
int n; scanf("%d",&n);
for(int a=;a<=n;a++)
{
f[a]=f[a-]; ADD(f[a],(a->>)-ceil(a*1.0/)+);
ADD(f[a],(a&) ? : -a/);
}
for(int a=;a*a<=n;++a)
if(n%a==)
{
divisor[++cnt]=a;
if(a*a!=n) divisor[++cnt]=n/a;
}
sort(divisor+,divisor+cnt+);
for(int i=;i<=cnt;i++)
for(int j=;j<i;j++)
if(divisor[i]%divisor[j]==) ADD(f[divisor[i]],mod-f[divisor[j]]);
g[]=;
for(int i=;i<=n;i++) g[i]=g[i-],ADD(g[i],g[i-]);
int ans=;
for(int i=;i<=cnt;i++) ADD(ans,1ll*f[divisor[i]]*g[n/divisor[i]-]%mod);
printf("%d",ans);
}

考场上WW的组合数,得了30,挂了30

#include<cstdio>
using namespace std;
int n;
int one[];
int C[][];
const int mod=1e9+;
bool check(int i,int j,int k)
{
if(!i || !j || !k) return false;
if(!((i<=j)&&(j<=k))) return false;
if(i+j<=k) return false;
if(j-i>=k) return false;
return true;
}
void pre()
{
for(int i=;i<=n;i++)
for(int j=;j<=i;j++)
for(int k=j;k<=i;k++)
if(check(j,i-j-k,k)) one[i]++;
for(int i=;i<=n;i++) C[i][]=;
for(int i=;i<=n;i++) C[][i]=;
for(int i=;i<=n;i++)
for(int j=;j<=i;j++)
C[i][j]+=C[i-][j-]+C[i-][j],C[i][j]%=mod;
int tot,ans=;
for(int i=;i<=n;i++)
if(n%i==)
{
tot=n/i;
tot--;
if(!tot) { ans+=one[i]; continue;}
for(int j=;j<=tot;j++) ans=(ans+1ll*one[i]*C[tot][j-]*j)%mod; }
printf("%d",ans);
}
int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%d",&n);
pre();
}

这题竟然是个容斥原理

解决本题的关键:行交换、列交换对答案不影响

将左视图按从下往上递减,正视图从左往右递减排列

那整张图的高度从左下到右上呈阶梯状递减

这样所有高度相同的呈现倒‘L’形,如下图所示蓝色部分

如果我们按高度递减的顺序依次计算每个倒‘L’形的方案数,那么这些倒‘L’形相对独立

答案就是所有倒‘L’形答案的乘积

如何计算单个倒‘L’形的答案?——容斥原理

假设上图为已经按高度排好序的图

设当前正在处理高度为h的倒‘L’形

令nn表示当前有nn行的左视图高度为h,mm表示当前有mm列的主视图高度为h

n表示当前有n行的左视图高度>=h,m表示当前有m列的主视图高度>=h

定义性质pk表示 在这nn行mm列中,有k行/列不满足看到的高度为h

那根据容斥原理,

不具有任何一个性质p的方案和=

全集-Σ|pi|+Σ|pi∩pj|-Σ|pi∩pj∩pk|+…+(-1)^m*|p1∩p2∩…∩pm|

也就是所有方案-所有1行/列不满足条件的方案+所有2行/列不满足条件的方案-……

如何求有k行/列不满足条件的方案数?

设现在要求在倒‘L’形中,有i行j列不满足条件的方案数A,i+j=k

那么A分为两部分

① i行j列不能满足条件的部分:

当前高度为h,不能满足条件,每一个各自可以填[0,h-1],每个格子有h种方案

所以此时方案数=h^ (n*m-(n-i)*(m-j))

② 倒‘L’形中其他位置可以任意填的部分

当前高度为h,任意填就是可以填[0,h],每个各自有h+1种方案

所以此时的方案数=(h+1)^((n-i)*(m-j)-(n-nn)*(m-mm))

这是选定i行j列,所以还要乘上在nn行中选i行,在mm列中选j列的方案

终上所述,每个倒‘L’形 的答案为 (-1)^(i+j)* C(nn,i)* C(mm,j)* h^ (n*m-(n-i)*(m-j)) * (h+1)^((n-i)*(m-j)-(n-nn)*(m-mm))

#include<cstdio>
#include<algorithm> using namespace std; typedef long long LL; #define N 51
#define H 10001
const int mod=1e9+; int a[H],b[H];
int n,m;
int C[N][N]; void pre(int k)
{
for(int i=;i<=k;i++) C[i][]=;
for(int i=;i<=k;i++)
for(int j=;j<=i;j++)
C[i][j]=(C[i-][j]+C[i-][j-])%mod;
} int pow(int a,int b)
{
int res=;
for(;b;b>>=,a=1ll*a*a%mod)
if(b&) res=1ll*res*a%mod;
return res;
} int cal(int n,int m,int nn,int mm,int h)
{
int res=,tmp;
for(int i=;i<=nn;++i)
for(int j=;j<=mm;++j)
{
tmp=1ll*pow(h,n*m-(n-i)*(m-j))*pow(h+,(n-i)*(m-j)-(n-nn)*(m-mm))%mod*C[nn][i]%mod*C[mm][j]%mod;
if((i+j)&) res=((res-tmp)%mod+mod)%mod;
else res+=tmp,res%=mod;
}
return res;
} int main()
{
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
int x;
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i) scanf("%d",&x),a[x]++;
for(int i=;i<=m;++i) scanf("%d",&x),b[x]++;
pre(max(n,m));
LL res=;
int nown=,nowm=;
for(int i=;i>=;i--)
if(a[i] || b[i])
{
nown+=a[i]; nowm+=b[i];
res=1ll*res*cal(nown,nowm,a[i],b[i],i)%mod;
}
printf("%I64d",res);
}

2017北京国庆刷题Day3 morning的更多相关文章

  1. 2017北京国庆刷题Day3 afternoon

    期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...

  2. 2017北京国庆刷题Day1 afternoon

    期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms   Memory Limit:128MB 题目 ...

  3. 2017北京国庆刷题Day7 morning

    期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...

  4. 2017北京国庆刷题Day5 afternoon

    期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)… ...

  5. 2017北京国庆刷题Day2 afternoon

    期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一 ...

  6. 2017北京国庆刷题Day2 morning

    期望得分:100+100+40=240 实际得分:100+40+0=140 T1 一道图论神题(god) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK ...

  7. 2017北京国庆刷题Day4 morning

    期望得分:0+40+30=70 实际得分:0+10+10=20 题目修改:只能由0变1,只能用一次操作 大模拟 #include<cstdio> #include<cstring&g ...

  8. 2017北京国庆刷题Day5 morning

    期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13……) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...

  9. 2017北京国庆刷题Day4 afternoon

    期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...

随机推荐

  1. Ubuntu16.04安装oracle-java8-installer

    本篇博客参考 1. 安装默认JRE/JDK 更新 sudo apt-get update 检查是否安装了Java java -version 如果返回The program java can be f ...

  2. 软工实践-Alpha 冲刺 (6/10)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成了主界面的基本布局 ...

  3. KMP的原理和代码实现(详细注释|参考多个博客总结|可作为模板)

    KMP算法解决的问题是字符匹配,是由Knuth–Morris–Pratt共同开发出来的,这个算法把字符匹配的时间复杂度缩小到O(m+n),而空间复杂度也只有O(m),n是target的长度,m是pat ...

  4. 通过js读取元素的样式

    /* * 通过元素.style.样式只能获取到内联样式的值,就是style写在元素里面的值,不能获取嵌入式和外联样式的值 * 所以如果要获取除内联样式后的值,就不能通过这个获取 * alert(box ...

  5. 201621123037《Java程序设计》第二周学习总结

    #Week02-Java基本语法与类库 1. 本周学习总结 关键词:常量池.对象.null.不可变性.string对象拼接.字符串池 关键概念之间的联系:Java中有常量池,超出常量池以外的就会新开辟 ...

  6. 对象库(UI MAP)

    目的:能够使用配置文件存储被测页面上元素的定位方式和定位表达式,做到定位数据和程序的分离. 测试程序写好以后,可以方便不具备编码能力的测试人员进行自定义修改和配置 : package dataDriv ...

  7. jenkin重新注册用户

    http://www.cnblogs.com/xiao-fy/

  8. spring mvc4 找不到静态文件js/css/html 404

    说明: http://localhost:8080 指向的目录是WEB-INF所在的目录,也就是说请求静态资源时都是从该根目录开始查找.建议将所有静态文件放到和WEB-INF同级的目录下. 以 htt ...

  9. 查询出menupath字段中 出现 “- "(横杆)大于3次的 记录

  10. node进程捕捉错误

    var childProcess = require('child_process'); var commitMessage = (function() { var spawn = childProc ...