Description

Solution

定义dp[i][j]为在1到i个数中选了j个数,并且保证选了i的选法总数。

dp[i][j]为所有满足A[k]>A[i]的k(k<i)的dp[k][j-1]之和。在处理完dp[i][j]后,在树状数组里A[i]位置填上dp[i][j-1]的值就好。这样可以优化一下复杂度。[A可能要离散化一下]

然后,容斥大法好~

定义g[x]为最终序列长度为x的方案数。由于x是从大变小,所有的g[i]都是已经处理完毕的了。

(似乎还有一种不用n2操作,直接扫一遍就好的方法,不知道是不是二项式反演)

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int mod=1e9+;
typedef long long ll;
int n,a[],t[],rk[];
bool cmp(int x,int y){return a[x]<a[y];}
ll dp[][],g[]; ll fac[],inv[];
void pre()
{
fac[]=fac[]=inv[]=inv[]=;
for (int i=;i<=n;i++)
{
fac[i]=fac[i-]*i%mod;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
for (int i=;i<=n;i++) inv[i]=inv[i]*inv[i-]%mod;
}
ll C(int x,int y){return fac[y]*inv[x]%mod*inv[y-x]%mod;} ll tree[];
void add(int id,ll x){for(;id<=n;id+=id&-id) tree[id]+=x,tree[id]%=mod;}
ll query(int id){ll re=;for(;id;id-=id&-id) re+=tree[id],re%=mod;return re;}
int main()
{
scanf("%d",&n);
pre();
for (int i=;i<=n;i++)
{
scanf("%d",&a[i]);t[i]=i;
}
sort(t+,t+n+,cmp);
int js=;
a[]=-;
for (int i=;i<=n;i++)
{
if (a[t[i]]!=a[t[i-]]) js++;
rk[t[i]]=js;
}
for (int i=;i<=n;i++) dp[i][]=;
for (int j=;j<=n;j++)
{
memset(tree,,sizeof(tree));
add(rk[j-],dp[j-][j-]);
for (int i=j;i<=n;i++)
{
dp[i][j]=query(rk[i]);
add(rk[i],dp[i][j-]);
}
} g[n]=dp[n][n];
for (int i=n-;i;i--)
{
for (int j=;j<=n;j++) g[i]+=dp[j][i]*fac[n-i]%mod,g[i]%=mod;
for (int j=i+;j<=n;j++)
g[i]-=C(i,j)*g[j]%mod*fac[j-i]%mod,g[i]%=mod;
}
ll ans=;
for (int i=;i<=n;i++) ans=(ans+g[i]+mod)%mod;
cout<<ans;
}

[2016北京集训测试赛7]isn-[树状数组+dp+容斥]的更多相关文章

  1. [2016北京集训测试赛15]statement-[线段树+拆环]

    Description Solution 由于题目要求,将a[i]->b[i](边权为i)后所得的图应该是由森林和环套树组合而成. 假如是树形结构,所有的t[i]就直接在线段树t[i]点的dfs ...

  2. hdu 5792(树状数组,容斥) World is Exploding

    hdu 5792 要找的无非就是一个上升的仅有两个的序列和一个下降的仅有两个的序列,按照容斥的思想,肯定就是所有的上升的乘以所有的下降的,然后再减去重复的情况. 先用树状数组求出lx[i](在第 i ...

  3. Luogu4528 CTSC2008 图腾 树状数组、容斥

    传送门 设$f_i$表示$i$排列的数量,其中$x$表示不确定 那么$$ans=f_{1324}-f_{1432}-f_{1243}=(f_{1x2x}-f_{1423})-(f_{14xx}-f_{ ...

  4. [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]

    Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...

  5. 2016北京集训测试赛(十一)Problem C: 树链问题

    Solution 智障暴力题, 每个点维护一下子树信息, 树剖就好了. 我居然还傻了写了一发毛毛虫... #include <cstdio> #include <cctype> ...

  6. 2016北京集训测试赛(十七)Problem C: 数组

    Solution 线段树好题. 我们考虑用last[i]表示\(i\)这个位置的颜色的上一个出现位置. 考虑以一个位置\(R\)为右端点的区间最远能向左延伸到什么位置: \(L = \max_{i \ ...

  7. 2016北京集训测试赛(十七)Problem B: 银河战舰

    Solution 好题, 又是长链剖分2333 考虑怎么统计答案, 我场上的思路是统计以一个点作为结尾的最长上升链, 但这显然是很难处理的. 正解的方法是统计以每个点作为折弯点的最长上升链. 具体的内 ...

  8. 2016北京集训测试赛(十六)Problem A: 任务安排

    Solution 这道题告诉我们, 不能看着数据范围来推测正解的时间复杂度. 事实证明, 只要常数足够小, \(5 \times 10^6\)也是可以跑\(O(n \log n)\)算法的!!! 这道 ...

  9. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

随机推荐

  1. 28、springboot整合RabbitMQ(2)

    1.监听 1.1.监听队列 如订单系统和库存系统 订单系统下订单之后将消息存放在消息队列中 库存系统需要时刻进行监听消息队列的内容,有新的订单就需要进行库存相关的操作   此时模拟监听消息队列中的Bo ...

  2. Level/levelup-2-API

    https://github.com/Level/levelup Special Notes What happened to db.createWriteStream() levelup(db[, ...

  3. HDU 1224 Free DIY Tour(spfa求最长路+路径输出)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1224 Free DIY Tour Time Limit: 2000/1000 MS (Java/Oth ...

  4. openstack neutron 简单理解

    分析1)位于最上层的Neutron Server充当一个门派中的“掌门人”角色(RESTful Server),负责接受来自外部门派(项目)的API请求,比如Nova API创建网络的请求.2)位于中 ...

  5. STM32 以太网学习

    STM32进行以太网通信,需要  了解一下内容: 硬件层:MAC控制器  和  PHY 和 变压器 . 软件层:网络协议栈,例如:lwip协议栈,RL-TCPnet协议栈,FreeRTOS-TCP协议 ...

  6. webapi中的模型验证

    mic: https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-valida ...

  7. Linux -- 目录基本操作(1)

    cd 切换目录 1.切换到指定目录下 #cd 相对/绝对目录 [root@localhost ~]# cd /home/tom/demo [root@localhost demo]# 2.切换到某个用 ...

  8. 获取Linux下的IP地址 java代码

    /** * 获取Linux下的IP地址 * * @return IP地址 * @throws SocketException */ public static String getLinuxLocal ...

  9. NOIP Day1总结

    Day1T1玄学考试 在开始之前,我犯了考前综合症,各种不安各种焦躁. 结果当我去到考场的时候,看了T1...... T1:road 这不是裸的原题么这!我当时心里瞬间想到积木大赛.这明显就是积木大赛 ...

  10. Difftime

    功 能:返回两个time_t型变量之间的时间间隔,即 计算两个时刻之间的时间差. 用 法: double difftime(time_t time2, time_t time1);