2017北京国庆刷题Day3 morning
期望得分: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的更多相关文章
- 2017北京国庆刷题Day3 afternoon
期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...
- 2017北京国庆刷题Day1 afternoon
期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms Memory Limit:128MB 题目 ...
- 2017北京国庆刷题Day7 morning
期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...
- 2017北京国庆刷题Day5 afternoon
期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)… ...
- 2017北京国庆刷题Day2 afternoon
期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一 ...
- 2017北京国庆刷题Day2 morning
期望得分:100+100+40=240 实际得分:100+40+0=140 T1 一道图论神题(god) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK ...
- 2017北京国庆刷题Day4 morning
期望得分:0+40+30=70 实际得分:0+10+10=20 题目修改:只能由0变1,只能用一次操作 大模拟 #include<cstdio> #include<cstring&g ...
- 2017北京国庆刷题Day5 morning
期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13……) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...
- 2017北京国庆刷题Day4 afternoon
期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...
随机推荐
- WIN 7 发布项目
本人工作都快两年了不知道web 怎么发布 今天我自己非常恼火!我就暗暗研究.希望能给新手指导 准备工作:WIN7 系统 .IIS 6.0.MVC (vs 新建mvc项目自带的项目) OK begin ...
- AOP:Spring的xml配置方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- c# webBrowser清除缓存问题
1.webBrowser的浏览器为ie. 2.通过清除ie缓存即可. 3.代码调用如下: public enum ShowCommands : int { SW_HIDE = , SW_SHOWNOR ...
- FPGA论文
基于 NetFPGA 的 VCP 网络的设计与实现 --可变结构拥塞控制协议(VCP),适应于高带宽时延乘积网络的显式拥塞控制协议 无源光网络(PON) 1.区块链技术发展,物联网设备激增,服务器压力 ...
- lintcode-129-重哈希
129-重哈希 哈希表容量的大小在一开始是不确定的.如果哈希表存储的元素太多(如超过容量的十分之一),我们应该将哈希表容量扩大一倍,并将所有的哈希值重新安排.假设你有如下一哈希表: size=3, c ...
- Spring MVC @RequestParam @RequestHeader @CookieValue用法
摘要: package com.hust.springmvc1; import org.springframework.stereotype.Controller; import org.spring ...
- 阿里巴巴分布式数据库服务DRDS研发历程
淘宝TDDL研发历史和背景 分布式关系型数据库服务(Distribute Relational Database Service,简称DRDS)是一种水平拆分.可平滑扩缩容.读写分离的在线分布式数据库 ...
- php 单文件测试代码时必加入的代码
有时候为了解决BUG,需要测试一些函数或代码最终实现的效果,来排除一些影响因素.这时候需要把代码单独拎出来,放在一个php单文件中来测试.在头部最好加上三句代码如下: <?php ini_set ...
- python的N个小功能(更新文件)
########################################################################## #对于第二份文件:第一份与第二份不相同,以第二份为 ...
- [AT2377] [agc014_e] Blue and Red Tree
题目链接 AtCoder:https://agc014.contest.atcoder.jp/tasks/agc014_e 洛谷:https://www.luogu.org/problemnew/sh ...