【ZOJ3929 The 16th Zhejiang University Programming ContestC】【DP】Deque and Balls n个数放入双端队列2^n种方案有多少个位置
2016-04-12 13:07
537 查看
Deque and Balls
Time Limit: 2 Seconds Memory Limit: 65536 KB
There are n balls, where the i-th ball is labeled as pi. You are going to put n balls into a deque. In the i-th
turn, you need to put the i-th ball to the deque. Each ball will be put to both ends of the deque with equal probability.
Let the sequence (x1, x2, ..., xn) be the labels of the balls in the deque from left to right. The beauty of the deque B(x1, x2,
..., xn) is defined as the number of descents in the sequence. For the sequence (x1, x2, ..., xn), a descent is a position i (1
≤ i < n) with xi > xi+1.
You need to find the expected value of B(x1, x2, ..., xn).
Deque is a double-ended queue for which elements can be added to or removed from either the front (head) or the back (tail).
The first line contains an integer n (2 ≤ n ≤ 100000) -- the number of balls. The second line contains n integers: p1, p2,
..., pn (1 ≤ pi ≤ n).
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e5+10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
int n, x;
int b
;
int lft
, rgt
;
void add(int &x, int y)
{
x += y;
if (x >= Z)x -= Z;
}
void modify(int a[], int x, int val)
{
for (; x <= n; x += x&-x)add(a[x], val);
}
int check(int a[], int x)
{
int ret = 0;
for (; x; x -= x&-x)add(ret, a[x]);
return ret;
}
int main()
{
b[0] = 1;for (int i = 1; i <= 1e5; ++i)b[i] = b[i - 1] * 2 % Z;
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
scanf("%d", &n);
for (int i = 1; i <= n; ++i)lft[i] = rgt[i] = 0;
scanf("%d", &x);
modify(lft, x, 2);
modify(rgt, x, 2);
int ans = 0;
for (int i = 2; i <= n; ++i)
{
scanf("%d", &x);
ans = ans * 2 % Z;
add(ans, check(lft, x - 1));
add(ans, (Z + check(rgt, n) - check(rgt, x)) % Z);
modify(lft, x, b[i-1]);
modify(rgt, x, b[i-1]);
}
printf("%d\n", ans);
}
return 0;
}
/*
【题意】
有n(1e5)个数。
每个数都有一个权值(1~n)
我们有一个双端队列,每个数加入到双端队列的时候,可以加在该队列的前部或者尾部。
这样我们最后一共可以生成2^n个队列。
我们对于这2^n个队列,都扫描一遍。
如果存在一个队列的一个位置i∈[1,n),满足a[i]>a[i+1],那么我们答案的贡献就+1
问你最后的答案是多少(mod (1e9+7))
【类型】
DP 树状数组
【分析】
这题我们可以DP来做。如何做呢?
我们用lft[i]表示数值为i的数出现在整个数列左侧的方案数
用rgt[i]表示数值为i的数出现在整个数列右侧的方案数
那么,当新的一个数加进来时——
1,之前的所有答案都要*2,因为队列的可能性种数*2了,所以之前的答案也要*2
2,对于之前的每个lft[i],它依然继续是lft的条件是当前的数放在了右侧,
这样的话,对于当步决策,使得之前lft[]变化的延展系数为1,所以lft[i]保留不变
3,对于之前的每个rgt[i],它依然继续是rgt的条件是当前的数放在了左侧,
这样的话,对于当步决策,使得之前rgt[]变化的延展系数为1,所以rgt[i]保留不变
于是,在ans*=2后,当步数新放置后,对答案的贡献是lft[1~x-1]+rgt[x+1~n]
这样我们就可以AC啦。
【时间复杂度&&优化】
O()
【数据】
input
3
1 2 3
output
detail
1 2
2 1
1 2 3
2 1 3
3 1 2
3 2 1
*/
Time Limit: 2 Seconds Memory Limit: 65536 KB
There are n balls, where the i-th ball is labeled as pi. You are going to put n balls into a deque. In the i-th
turn, you need to put the i-th ball to the deque. Each ball will be put to both ends of the deque with equal probability.
Let the sequence (x1, x2, ..., xn) be the labels of the balls in the deque from left to right. The beauty of the deque B(x1, x2,
..., xn) is defined as the number of descents in the sequence. For the sequence (x1, x2, ..., xn), a descent is a position i (1
≤ i < n) with xi > xi+1.
You need to find the expected value of B(x1, x2, ..., xn).
Deque is a double-ended queue for which elements can be added to or removed from either the front (head) or the back (tail).
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:The first line contains an integer n (2 ≤ n ≤ 100000) -- the number of balls. The second line contains n integers: p1, p2,
..., pn (1 ≤ pi ≤ n).
Output
For each test case, if the expected value is E, you should output E⋅2n mod (109 + 7).Sample Input
2 2 1 2 3 2 2 2
Sample Output
2 0
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e5+10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
int n, x;
int b
;
int lft
, rgt
;
void add(int &x, int y)
{
x += y;
if (x >= Z)x -= Z;
}
void modify(int a[], int x, int val)
{
for (; x <= n; x += x&-x)add(a[x], val);
}
int check(int a[], int x)
{
int ret = 0;
for (; x; x -= x&-x)add(ret, a[x]);
return ret;
}
int main()
{
b[0] = 1;for (int i = 1; i <= 1e5; ++i)b[i] = b[i - 1] * 2 % Z;
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
scanf("%d", &n);
for (int i = 1; i <= n; ++i)lft[i] = rgt[i] = 0;
scanf("%d", &x);
modify(lft, x, 2);
modify(rgt, x, 2);
int ans = 0;
for (int i = 2; i <= n; ++i)
{
scanf("%d", &x);
ans = ans * 2 % Z;
add(ans, check(lft, x - 1));
add(ans, (Z + check(rgt, n) - check(rgt, x)) % Z);
modify(lft, x, b[i-1]);
modify(rgt, x, b[i-1]);
}
printf("%d\n", ans);
}
return 0;
}
/*
【题意】
有n(1e5)个数。
每个数都有一个权值(1~n)
我们有一个双端队列,每个数加入到双端队列的时候,可以加在该队列的前部或者尾部。
这样我们最后一共可以生成2^n个队列。
我们对于这2^n个队列,都扫描一遍。
如果存在一个队列的一个位置i∈[1,n),满足a[i]>a[i+1],那么我们答案的贡献就+1
问你最后的答案是多少(mod (1e9+7))
【类型】
DP 树状数组
【分析】
这题我们可以DP来做。如何做呢?
我们用lft[i]表示数值为i的数出现在整个数列左侧的方案数
用rgt[i]表示数值为i的数出现在整个数列右侧的方案数
那么,当新的一个数加进来时——
1,之前的所有答案都要*2,因为队列的可能性种数*2了,所以之前的答案也要*2
2,对于之前的每个lft[i],它依然继续是lft的条件是当前的数放在了右侧,
这样的话,对于当步决策,使得之前lft[]变化的延展系数为1,所以lft[i]保留不变
3,对于之前的每个rgt[i],它依然继续是rgt的条件是当前的数放在了左侧,
这样的话,对于当步决策,使得之前rgt[]变化的延展系数为1,所以rgt[i]保留不变
于是,在ans*=2后,当步数新放置后,对答案的贡献是lft[1~x-1]+rgt[x+1~n]
这样我们就可以AC啦。
【时间复杂度&&优化】
O()
【数据】
input
3
1 2 3
output
detail
1 2
2 1
1 2 3
2 1 3
3 1 2
3 2 1
*/
相关文章推荐
- 【HDU5188 BestCoder Round 33C】【贪心排序+DP】zhx and contest 考试不被怀疑作弊条件下达到至少m分的最少时间
- 【HDU5569 BestCoder Round 63 (div1)B】【DP】matrix 向右走向下走最大乘积和
- 【HDU5568 BestCoder Round 63 (div1)A】【DP java高精度】sequence2 长度恰好为m的LIS数
- 【Codeforces Round 333 (Div 2)E】【期望DP概率做法 树状数组转前缀和】Kleofáš and the n-thlon n场比赛m个人获得总名次的期望
- 【Codeforces Testing Round 12C】【DP 树状数组优化】Subsequences n个不同数,长度为m的LIS数
- 【Codeforces Beta Round 2B】【贪心 DP】The least round way 从(1,1)走到(n,n)乘积尾数0尽可能少
- 【2015ZUFE新生赛网络同步赛H】【水题 DP】会长晨刷记 步长1~4 不踩水坑从1到m
- 【2015ZUFE新生赛网络同步赛M】【DP 打表 二分】GW I (3) 暴力预处理+分类打表二分查找
- 【2015广东工业大学新生赛F】【脑洞 DP打表找规律】有钱的wingkou 取走2个放回1个问最后剩下为0的概率
- 【Codeforces Round 271 (Div 2)D】【DP】Flowers 黑色必须连续摆放k,长度为n的摆放方案数
- 【Codeforces Round 274 (Div 2)E】【DP 成段更新 打标记法 滚动数组】Riding in a Lift 乘坐k次电梯避免到达b层的方案数
- 【Codeforces Round 273 (Div 2)D】【DP 滚动数组】 Red-Green Towers 两种颜色积木拼搭最高锯齿楼每层颜色相同的总方案数
- 【Codeforces Round 336 (Div 2) C】【贪心 DP思维】Chain Reaction 每个灯塔位置为a[]破坏b[]范围所有灯塔 设置一个灯塔使得最多灯塔被保留
- 【Manthan, Codefest 16E】【DP 从右向左线性扫描不用ST-RMQ】Startup Funding 最大的min(取min,取max) + n值选k最小做权的期望
- 【ZOJ3916 2016年浙大2月月赛B】【贪心 STL-SET】Buy Cakes n蛋糕k张折扣券蛋糕双价最多能买蛋糕数
- 【ZOJ3919 2016年浙大2月月赛E】【简单计算几何 贪心】Ellipse 椭圆内切圆外切平行四边形最大最小面积
- 【ZOJ3921 2016年浙大2月月赛G】【爆搜+智商贪心剪枝 好题】Guan Dan 2副牌取27张最少出光牌次数
- 【ZOJ3921 2016年浙大2月月赛I】【物理题 底乘高积分式思维】In the Rain 圆柱体人行走 吸收雨体积
- 【ZOJ3921 2016年浙大2月月赛J】【题目观察 暴力 大组合数】Musical Notes n个数,数值为1 2 4 8 16,和恰为m方案数
- 【HDU6197 2017 ACM ICPC Asia Regional Shenyang Online D】【LIS 最长不下降序列】array array array 数列删除恰好K个数,使得恰好