【bzoj3866】The Romantic Hero dp

题目描述

给你n个数,从中选出两个不相交非空集合S和T,使得S中的每一个元素都在T集合的前面,并且S集合中的所有数的亦或等于T集合中的所有数的与,求方案数 mod 10^9+7。

输入

The first line contains an integer T, denoting the number of the test cases.

For each test case, the first line contains a integers n.

The next line contains n integers a_1,a_2,...,a_n which are separated by a single space.

n<=10^3, 0 <= a_i <1024, T<=20.

输出

For each test case, output the result in one line.

样例输入

2
3
1 2 3
4
1 2 3 3

样例输出

1
4



题解

dp

设$s[i][j]$表示前$i$个数选$i$,选出的数的亦或为$j$的方案数,那么直接使用前缀和优化,转移时枚举之前的$j$,与当前位置计算得出新的$j$即可。

设$t[i][j]$表示从$i$到$n$选$i$,选出的数的与为$j$的方案数,那么转移同理。

最后枚举$S$/$T$集合的第一个数,使用乘法原理计算即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define m 1024
#define mod 1000000007
using namespace std;
int a[m] , fs[m][m] , ss[m][m] , ft[m][m] , st[m][m];
int main()
{
	int T;
	scanf("%d" , &T);
	while(T -- )
	{
		int n , i , j , ans = 0;
		scanf("%d" , &n);
		for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]);
		memset(fs , 0 , sizeof(fs)) , memset(ss , 0 , sizeof(ss));
		memset(ft , 0 , sizeof(ft)) , memset(st , 0 , sizeof(st));
		ss[0][0] = st[n + 1][m - 1] = 1;
		for(i = 1 ; i <= n ; i ++ )
		{
			for(j = 0 ; j < m ; j ++ ) fs[i][j ^ a[i]] = (fs[i][j ^ a[i]] + ss[i - 1][j]) % mod;
			for(j = 0 ; j < m ; j ++ ) ss[i][j] = (ss[i - 1][j] + fs[i][j]) % mod;
		}
		for(i = n ; i ; i -- )
		{
			for(j = 0 ; j < m ; j ++ ) ft[i][j & a[i]] = (ft[i][j & a[i]] + st[i + 1][j]) % mod;
			for(j = 0 ; j < m ; j ++ ) st[i][j] = (st[i + 1][j] + ft[i][j]) % mod;
		}
		for(i = 1 ; i < n ; i ++ )
		{
			ss[i][0] -- ;
			for(j = 0 ; j < m ; j ++ ) ans = (ans + (long long)ss[i][j] * ft[i + 1][j]) % mod;
		}
		printf("%d\n" , ans);
	}
	return 0;
}
时间: 2024-08-28 08:40:17

【bzoj3866】The Romantic Hero dp的相关文章

【BZOJ3866】The Romantic Hero “再不刷它就土了”系列

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42612069 其实我就是觉得原创的访问量比未授权盗版多有点不爽233... 话说其实我并不知道它会不会变成土豪题. 应该会吧?先刷了吧. 题意: 给出一个数列,然后取一个两个子序列A.B, 使得A严格在B前面. 然后要求A的异或和(^)等于B的与和(&). 题解: 动规. 注意判重..没什么好注意的,不判重样例都过不去233. 啊.下午好颓废~~~不爽啊~~~这道题算是随便签个到吧? 代

HDU 4901 The Romantic Hero(DP)

HDU 4901 The Romantic Hero 题目链接 题意:给定一个序列,要求找一个分界点,然后左边选一些数异或和,和右边选一些数且和相等,问有几种方法 思路:dp,从左往右和从右往左dp,求出异或和且的个数,然后找一个分界点,使得一边必须在分界点上,一边随意,然后根据乘法原理和加法原理计算 代码: #include <cstdio> #include <cstring> typedef __int64 ll; const int N = 1024; const int

hdu 4901 The Romantic Hero (dp+背包问题)

题意: 有n个数,从n个数中选出两个集合s和集合t,保证原序列中,集合s中的元素都在 集合t中元素的左边.且要求集合s中元素做抑或运算的值与集合t中元素做与运算的 值相等.问能选出多少种这样的集合s和t. 算法: 左右dp. 用dp[i][j]表示前i个数 做抑或运算得到j的方法数.最后一个值取不取到都不一定. 故为背包的问题.右边也是一样. 枚举时可能出现重复.枚举到第i个和枚举第i+1个可能重复.所以要枚举一个中间值. 这个中间值是归到s集的,因为抑或支持逆运算,而与是不支持的. 所以最后d

hdoj 4901 The Romantic Hero DP hdoj 4902 Nice boat 线段树

惨遭丽洁乱虐..这一场也是比得乱七八糟的,4902本是丽洁定义比较难的题,结果数据随机的,被许多暴力水过了..4905考察的是四边形不等式优化,但是这道题的dp方程实际上不满足该优化的条件..朴素的o(n^3)会超时,所以这题目前是没有正解了..我还写了个这题的贪心,强度挺高,可以对大概一半数据,错的误差也只有个位数,还揪出官方第五个数据..朴素dp和贪心跑这个数据都比官方数据多了1,也就证明这题不满足四边形不等式优化的条件.. http://acm.hdu.edu.cn/showproblem

HDU4901 The Romantic Hero DP

题意:给你n个数,问你将数分成两个数组,S,T ,T 中所有元素的需要都比S任意一个大,问你S中所有元素进行 XOR 操作和 T 中所有元素进行 &操作值相等的情况有多少种. 解题思路:两个二维DP,等于背包问题,dpy[i][j] 代表选 数组 S 前 i 个数 状态为 j 的 情况有多少种.(这个是从前往后dp的) 然后我们还需要知道 dpx[i][j] ,代表选 T 数组 i-n个数的时候状态为 j 的情况数, (从后往前dp) 答案就是中间过程中  dpx[i]][j], i 必选的那种

HDU4901:The Romantic Hero(DP)

Problem Description There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can't refus

【BZOJ1786】[Ahoi2008]Pair 配对 DP

[BZOJ1786][Ahoi2008]Pair 配对 Description Input Output Sample Input 5 4 4 2 -1 -1 3 Sample Output 4 题解:结论!!!为了使逆序对最少,我们在-1位置填入的数一定是单调不减的.(可以用反证法证明,很简单.) 所以DP,我们用f[i][j]表示枚举到第i个数,上一个在-1位置填入的数是j个最少逆序对个数.然后转移也很简单~ #include <cstdio> #include <cstring&g

【BZOJ2064】分裂 状压DP

[BZOJ2064]分裂 Description 背景:和久必分,分久必和...题目描述:中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力.同时经常搞OI的他把这个变成了一个数学模型.假设中国的国土总和是不变的.每个国家都可以用他的国土面积代替,又两种可能,一种是两个国家合并为1个,那么新国家的面积为两者之和.一种是一个国家分裂为2个,那么2个新国家的面积之和为原国家的面积. WJMZBMR现在知道了很遥远的过去中国的状态,又知道了中国现在的状态,想知道至少要几次操作(

【BZOJ2510】弱题 期望DP+循环矩阵乘法

[BZOJ2510]弱题 Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M),若这个球标号为k(k < N),则将它重新标号为k + 1:若这个球标号为N,则将其重标号为1.(取出球后并不将其丢弃) 现在你需要求出,经过K次这样的操作后,每个标号的球的期望个数. Input 第1行包含三个正整数N,M,K,表示了标号与球的个数以及操作次数. 第2行包含N个