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ㄒ)/~ ...
随机推荐
- 04慕课网《进击Node.js基础(一)》HTTP讲解
HTTP:通信协议 流程概述: http客户端发起请求,创建端口默认8080 http服务器在端口监听客户端请求 http服务器向客户端返回状态和内容 稍微详细解析: 1.域名解析:浏览器搜素自身的D ...
- postion一句话很管用
relative和absolute有本质区别,relative是相对与postion为默认值的时候元素自身位置来定位:而absolute是相对最近position为relative或absolute的 ...
- Qt多线程-总结QThread-QThreadPool-QtConcurrent
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-总结QThread-QThreadPool-QtConcurrent 本文 ...
- 【第三周】【】cppunit!
coding.net地址:https://coding.net/u/Boxer_ ssh:git@git.coding.net:Boxer_/homework.git https://coding.n ...
- Win server 2016 升级 Win server 2019 [测试验证]
. 给win server 2016 挂在 win server 2019 的安装盘 2. 点击setup 直接进行安装操作 选择不下载更新, 然后到达输入序列号的界面 序列号为: WMDGN-G9 ...
- windows系统,可以ping通IP但是不能ping通网址的解决方法
之前慌忙之中遇到过一次,当时是客户比较着急使用就没有怎么折腾,什么数据当时都没留下反正是各种方法都尝试过了,但是就是ping IP是可以通的,但是域名就是不解析,后来有个群友也是遇见了这个问题(我当时 ...
- android studio 运行太慢了
Android Studio每次升级/安装 Android Studio 之后最好都修改一下这个参数:到 Android Studio 安装目录,找到 bin/studio(64?).vmoption ...
- 平衡树以及AVL树
平衡树是计算机科学中的一类数据结构. 平衡树是计算机科学中的一类改进的二叉查找树.一般的二叉查找树的查询复杂度是跟目标结点到树根的距离(即深度)有关,因此当结点的深度普遍较大时,查询的均摊复杂度会上升 ...
- jQuery 获取和设置radio 和 checkbox 值的操作
jquery 中的val(),可以取值也可赋值,表单元素中的radio和checkbox是比较常用的控件,下面说说对它们的取值和赋值的使用 1.取值 表单如下: <div class=" ...
- 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息
题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...