BestCoder Round #40 解题报告
这场是第一场没有米的BC...
大概也是想震一震那些一听说没米了就不打BC的人吧
这次的题目质量比以往高了许多
(然而我并没有打这一场BC
但是今天下午到现在做的过程中真的学到了不少知识呢

A题略水...
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
int T,n;
int main(){
scanf("%d",&T);
while (T--){
scanf("%d",&n);
int tmp;
for (int i=;i<=sqrt(n);i++) if (n%i==) tmp=i;
printf("%d\n",*(n/tmp+tmp));
}
return ;
}
然而第二题就不是非常简单的呢...

开始啊..我打算数位DP搞搞,然而突然发现排列是不能有重复数字的啊...
想到一个容易入手的状态 也就解决了这道题
我们需要让这些排列都小于读进来的排列
然后思考一下这些排列都有什么共性呢?
显然一定是由一段与排列相同的数字组成的前缀构成的,而接下来的一位一定小于排列,剩下的就随意了
这么一来好像问题就迎刃而解了
枚举与原串相同的位数(0~n-1),以及接下来一位的数字(小于原串该位置上的数字且在前面的位置中没出现过)

设当前枚举的黄色部分的位置为i,那么显然这样的字符串有(n-i)!种(即后面蓝色部分的n-i个数字的全排列)
这些字符串对答案的贡献分几部分考虑
1)红色部分内部的逆序对*(n-i)!,原串所有的前缀的逆序对数量可以通过树状数组预处理出
2)红色部分与黄色+蓝色部分的逆序对数,
可以用树状数组维护黄色+蓝色部分的值(即每向后走一格就将前一个数从树状数组中删去)
然后枚举红色部分的每一个元素,统计逆序对数,最后乘上(n-i)!
3)黄色部分与蓝色部分的逆序对数,直接与红色部分一样的答案最后-1即可(即把自己与自己减掉),
当然get的时候传参改成数值-1也是可以的
4)蓝色部分的逆序对数,这个在(n-i)!个字符串中都是不一样的,于是我们可以考虑总数
对于一个n个数的排列,我们考虑其中的两个数,它们成为逆序对的次数为C(n,2)*(n-2)!
所以逆序对总数为C(n,2)^2*(n-2)!
然后这道题就做完了,但是却对拍了一个下午都没找出哪里写错...
最后写两点做题过程中积累的东西吧...
1)C++的数组和Pas毕竟不一样...赋值啊什么的不能顶到maxn..而且居然本地不会出现RE
2)while not eof do 在C++里是以很奇怪的方式替代的呢...
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cstring>
#define tt 1000000007
#define maxn 110
#define ll long long
using namespace std;
int n,a[maxn],tr[maxn];
ll w[maxn],p[maxn],b[maxn];
bool used[maxn];
int get(int x){
int tmp=;
while (x) tmp+=tr[x],x-=x&(-x);
return tmp;
}
void put(int x,int y){
while (x<=n) tr[x]+=y,x+=x&(-x);
}
void build(){
w[]=;for(int i=;i<maxn;i++) w[i]=(w[i-]*i)%tt;
p[]=;for (int i=;i<maxn;i++) {
ll tmp=i*(i-)/;
p[i]=((tmp*tmp%tt)*w[i-])%tt;
}
}
void solve(){
ll ans=;
memset(tr,,sizeof(tr));
for (int i=;i<=n;i++) b[i]=(b[i-]+get(n-a[i]+))%tt,put(n-a[i]+,);
memset(tr,,sizeof(tr));
memset(used,true,sizeof(used));
for (int i=;i<=n;i++) put(i,);
for (int i=;i<=n;i++){
if (i!=) put(a[i-],-),used[a[i-]]=false;
for (int j=;j<a[i];j++) if (used[j]){
ll tmp=b[i-];for (int k=;k<i;k++) tmp=(tmp+get(a[k]))%tt;
if (j!=) tmp=(tmp+get(j-))%tt;
tmp=((tmp*w[n-i])+p[n-i])%tt;
ans=(ans+tmp)%tt;
}
}
cout<<ans<<endl;
}
int main(){
build();
while (cin>>n){
for (int i=;i<=n;i++) scanf("%d",a+i);
solve();
}
return ;
}

浓浓的数学味...于是又得去补充几个知识了呢
首先带取模的组合数是不能直接求解的...因为一旦C(n,m)中假设n>模数p,n!中就会出现p这个因子
然后C(n,m)就不可避地计算出了0...
这个时候要用到Lucas定理,递归定义
ll lucas(int n,int m){
if (m==) return ;
if (n<tt&&m<tt) return c(n,m);
return lucas(n/tt,m/tt)*lucas(n%tt,m%tt)%tt;
}
另一个就是连续的组合数快速求解...
刚开始我一直在寻找同一行之间的关系..因为毕竟之前如果是整行是可以直接算的
然而实际上列存在着一定的关系

我们考虑这样一列上连续一段的求解(如图中红色部分)
根据杨辉三角的构造方法,C(n,m)=C(n-1,m)+C(n-1,m-1)
我们设4号格子的位置为(i,a)
最顶端红色格子的位置为(i,b)
C(a+1,i+1)=C(a,i)+C(a,i+1) → C(a,i)=C(a+1,i+1)-C(a,i+1)
显然...sigma(C(i,j))(a<=j<=b)=C(a+1,i+1)-C(b,i+1)
在图中也就是橙色格子-蓝色格子
然后对于每一列求解就可以了,但是要注意可能a,b不是真正的a,b
因为我们现在考虑的是建立在红色部分都至少为1的基础上的,于是对于每一列都要对行标号进行处理
另外还要注意,即使实际代表意义上不可能但取模意义下的减法可能会减出负的,也要处理
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 100010
#define ll long long
int x1,y1,x2,y2,tt;
ll fac[maxn],inv[maxn];
int max(int a,int b){
if (a>b) return a;
return b;
}
ll mul(ll a,ll b){
ll ans=,w=a;
while (b){
if (b%==) ans=ans*w%tt;
w=w*w%tt;b=b>>;
}
return ans;
}
void build(){
fac[]=;for (int i=;i<maxn;i++) fac[i]=fac[i-]*i%tt;
inv[]=;for (int i=;i<maxn;i++) inv[i]=mul(fac[i],tt-);
}
ll c(int n,int m){
return fac[n]*inv[m]%tt*inv[n-m]%tt;
}
ll lucas(int n,int m){
if (m==) return ;
if (n<tt&&m<tt) return c(n,m);
return lucas(n/tt,m/tt)*lucas(n%tt,m%tt)%tt;
}
ll query(int n,int m){
if (n<m) return ;
return lucas(n,m);
}
void solve(){
ll ans=;
for (int i=y1;i<=y2;i++) {
if (x2<i) continue;
int l=max(x1,i),r=x2;
if (l==i){l++;ans=(ans+)%tt;}
ans=(ans+query(r+,i+)-query(l,i+)+tt)%tt;
}
printf("%lld\n",ans);
}
int main(){
while (scanf("%d",&x1)!=EOF){
scanf("%d%d%d%d",&y1,&x2,&y2,&tt);
build();
solve();
}
return ;
}
BestCoder Round #40 解题报告的更多相关文章
- BestCoder Round #86 解题报告
A.Price List Sol 求和查询 Code #include<cstdio> #include<algorithm> #include<iostream> ...
- BestCoder Round #75 解题报告
King's Cake [思路] 递推 公式:f(n,m)=f(max(m,n-m),min(m,n-m))+1,n>m [代码] #include<cstdio> #include ...
- BestCoder Round #76 解题报告
DZY Loves Partition [思路] 贪心 [代码] #include <iostream> using namespace std; typedef long long ll ...
- BestCoder Round #39 解题报告
现场只做出前三题w 不过不管怎样这既是第一次认真打BC 又是第一次体验用在线编译器调代码 订正最后一题花了今天一整个下午(呜呜 收获还是比较大的^_^ Delete wld有n个数(a1,a2,... ...
- 浙江省队选拔 ZJOI2015 (Round 1) 解题报告
最近莫名其妙地喜欢上了用这种格式写各省省选的全套题解= = 今年浙江省选的出题人是算法竞赛界传说级人物陈立杰,看样子他的出题风格很有特点……ABC三题难度是严格递减的,感觉如果在做第一题的时候被卡住的 ...
- Codeforces Round #300 解题报告
呜呜周日的时候手感一直很好 代码一般都是一遍过编译一遍过样例 做CF的时候前三题也都是一遍过Pretest没想着去检查... 期间姐姐提醒说有Announcement也自信不去看 呜呜然后就FST了 ...
- BestCoder Round #40
T1:Tom and pape (hdu 5224) 题目大意: 给出一个矩形面积N,求周长的最小值.(长&&宽&&面积都是正整数) N<=109 题解: 没啥好 ...
- Mango Weekly Training Round #6 解题报告
比赛链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41856#overview A.多种解法.可以dfs倒序染色,如mathlove ...
- Mango Weekly Training Round #3 解题报告
A. Codeforces 92A Chips 签到题.. #include <iostream> #include <cstdio> #include <cstring ...
随机推荐
- 第11章 认识和学习bash
认识bash这个shell 硬件.内核和shell 用户操作计算机流程如下: 用户——>用户界面(shell,KDE,application)——>核心(kernel)——>硬件(h ...
- Spring Boot(八)集成Spring Cache 和 Redis
在Spring Boot中添加spring-boot-starter-data-redis依赖: <dependency> <groupId>org.springframewo ...
- eclipse取消validation验证
点击按钮如下:window-Preferences-Validation.如图. 然后把build里面的都取消.即可.
- Struts2(二)
以下内容是基于导入struts2-2.3.32.jar包来讲的 1.关于StrutsPrepareAndExecuteFilter 启动StrutsPrepareAndExecuteFilter时加载 ...
- 【C】树
1.子树是不相交的 2.除了根节点,每个节点有且仅有一个父节点 3.一颗n个节点的树有n-1条边 儿子兄弟表示法 满二叉树与完全二叉树 1.满二叉树是除了叶子节点,每一个节点都有两个子节点,并按顺序排 ...
- redis 同步化操作
异步化操作是很麻烦的的.不好控.下面介绍个同步化的库bluebird.用法很简单.看下你还子就知道了 const redis = require('redis'); const bluebird = ...
- js & array to string
js & array to string https://stackoverflow.com/questions/13272406/convert-string-with-commas-to- ...
- BZOJ 1177 Oil(特技枚举)
对于三个正方形的位置一共有六种情况. 预处理出(i,j)左上角,左下角,右上角,右下角区域内最大权值的正方形. 枚举分界线更新答案. 刚开始想了一个错误的DP也是蠢啊. #include<set ...
- mysql索引长度的一些限制
一.myisam存储引擎 1. 数据库版本:阿里云RDS MySQL5.1 mysql> select @@version;+-------------------------------+| ...
- [HNOI2011]XOR和路径 概率期望 高斯消元
题面 题解:因为异或不太好处理,,,因此按位来算,这样最后的答案就是每一位上的值乘对应的权值再求和.本着期望要倒退的原则,,,我们设$f[i]$表示从$i$到$n$,xor和为1的概率.那么观察$xo ...