CodeForces - 691E Xor-sequences 【矩阵快速幂】
题目链接
http://codeforces.com/problemset/problem/691/E
题意
给出一个长度为n的序列,从其中选择k个数 组成长度为k的序列,因为(k 有可能 > n) 那么数字是可以重复选择的
使得 aj 属于 a1 -> ak-1 满足 aj ^ aj + 1 中二进制表示中1的个数是3的倍数
思路
很显然 当k == 1的时候,不存在 aj 属于 a1 -> a0 那么 自然是满足的 也就是说 k == 1 的时候 答案就是n
那么 k == 2 的时候 用一个二维01矩阵表示 a[i] ^ a[j] 是否满足条件 如果是 就为1
最后把这个二维矩阵的和 加起来
然后是 k >= 3 的情况
根据矩阵乘法的性质
我们知道 矩阵a * 矩阵b = 矩阵ans
ans[i][j] = a[i][1] * b[1][j] + …… + a[i][n - 1] * b[n - 1][j]
那么很显然 当 k == 3的时候
a[i][1] * b[1][j] 表示的是 数列 arr[i] arr[1] arr[j] 这个数列是否满足题目条件
加入 易知 只有当 arr[i][1] == 1 && arr[1][j] == 1的时候 才是符合的
那么其相乘起来 也是1 是一个长度为3 的满足条件的序列
由此观之,如果 k == 3 只要算 k == 2 的时候 构造的那个矩阵 的 平方 再求和 就是答案
那么 k > 3的时候 答案就是 对 k == 2 的那个矩阵 算 k - 1次幂 就可以
用矩阵快速幂优化
AC代码
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define pb push_back
#define fi first
#define se second
#define L(on) ((on)<<1)
#define R(on) (L(on) | 1)
#define mkp(a, b) make_pair(a, b)
#define bug puts("***bug***");
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define CLR(a, b) memset(a, (b), sizeof(a));
#define syn_close ios::sync_with_stdio(false); cin.tie(0);
#define sp system("pause");
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector < vi > vvi;
const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;
inline int read()
{
char c = getchar(); int ans = 0, vis = 1;
while (c < '0' || c > '9') { if (c == '-') vis = -vis; c = getchar(); }
while (c >= '0' && c <= '9') { ans = ans * 10 + c - '0'; c = getchar(); }
return ans * vis;
}
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int maxn = (int)1e2 + 10;
const int MAXN = (int)1e4 + 10;
const ll MOD = (ll)1e9 + 7;
int n;
ll k;
ll arr[maxn];
struct Matrix
{
ll G[maxn][maxn];
int len;
Matrix () {}
Matrix operator * (const Matrix& r) const
{
Matrix tmp; tmp.len = len;
CLR(tmp.G, 0);
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
for (int k = 0; k < len; k++)
tmp.G[i][j] = (tmp.G[i][j] + G[i][k] * r.G[k][j]) % MOD;
return tmp;
}
}base;
Matrix pow_mod(Matrix base, ll count)
{
Matrix ans; ans.len = base.len;
CLR(ans.G, 0);
for (int i = 0; i < ans.len; i++)
ans.G[i][i] = 1;
while (count)
{
if (count & 1)
ans = ans * base;
base = base * base;
count >>= 1;
}
return ans;
}
ll ok(ll x)
{
ll ans = 0;
while (x)
{
if (x & 1) ans++;
x >>= 1;
}
return (ans % 3 == 0);
}
void input()
{
scanf("%d%lld", &n, &k);
for (int i = 0; i < n; i++)
scanf("%lld", arr + i);
base.len = n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
base.G[i][j] = ok(arr[i] ^ arr[j]);
}
void solve()
{
base = pow_mod(base, k - 1);
ll ans = 0;
for (int i = 0; i < base.len; i++)
for (int j = 0; j < base.len; j++)
ans = (ans + base.G[i][j]) % MOD;
cout << ans << endl;
}
int main()
{
input(); solve();
}
CodeForces - 691E Xor-sequences 【矩阵快速幂】的更多相关文章
- Codeforces 691E题解 DP+矩阵快速幂
题面 传送门:http://codeforces.com/problemset/problem/691/E E. Xor-sequences time limit per test3 seconds ...
- Codeforces 691E Xor-sequences(矩阵快速幂)
You are given n integers a1, a2, ..., an. A sequence of integers x1, x2, ..., xk is called a & ...
- Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)
题目链接:http://codeforces.com/problemset/problem/450/B 题意很好懂,矩阵快速幂模版题. /* | 1, -1 | | fn | | 1, 0 | | f ...
- Codeforces 450B div.2 Jzzhu and Sequences 矩阵快速幂or规律
Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, ple ...
- codeforces 450B B. Jzzhu and Sequences(矩阵快速幂)
题目链接: B. Jzzhu and Sequences time limit per test 1 second memory limit per test 256 megabytes input ...
- Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check
A B C D 给你一个联通图 给定S,T 要求你加一条边使得ST的最短距离不会减少 问你有多少种方法 因为N<=1000 所以N^2枚举边数 迪杰斯特拉两次 求出Sdis 和 Tdis 如果d ...
- Xor-sequences CodeForces - 691E || 矩阵快速幂
Xor-sequences CodeForces - 691E 题意:在有n个数的数列中选k个数(可以重复选,可以不按顺序)形成一个数列,使得任意相邻两个数异或的结果转换成二进制后其中1的个数是三的倍 ...
- codeforces 691E 矩阵快速幂+dp
传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...
- codeforces 691E Xor-sequences 矩阵快速幂
思路:刚开始 n个元素,a[i][j]代表以i开头,j结尾的二元组符合条件的有多少 这是等于长度为2的数量 长度为3的数量为a*a,所以长度为n的数量是a^(k-1) 然后就是矩阵快速幂,然而我并不能 ...
随机推荐
- mysql5.7.22 zip 版安装
2.将zip文件解压到本地,本文解压到如下目录:D:\softwares\mysql-5.7.14-winx64 3.新建一个配置文件(my.ini)用于配置字符集.端口等信息,用以覆盖原始的配置文件 ...
- VMware虚拟机 Ubuntu 实用技巧 (2)桥接模式连接网络与网卡的配置
1.先用ifconfig查看当前的网卡配置,一般没有进行设置之前,打印的信息如下所示. ens33 Link encap:以太网 硬件地址 02:0c:29:c6:be:c7 inet6 地址: fe ...
- OpenCV中Kinect的使用(1)
图像处理中一般为了更好的获取外部信息都会使用到Kinect,其优势在于除了传统的RGB摄像头之外,还拥有一个获取深度信息的3D深度感应器,因此可以获得外界物体的3维信息实现物体的跟踪.手势识别等各项功 ...
- TelephonyManager&GsmCellLocation类的方法详解
转载:http://blog.163.com/zhangzheming_282/blog/static/117920962011101944356511/ TelephonyManager类 主要提供 ...
- Linux 下 -bash: mysql: command not found解决办法
-bash: mysql: command not found 1.vim ~/.bash_profile 最下面写 export PATH=$PATH:/usr/local/mysql/bin(你的 ...
- git的优秀教程
1.csdn地址:http://blog.csdn.net/qq_15037231/article/details/73864293 2.廖雪峰的git教程 地址:https://www.liaox ...
- [JAVA · 0基础]:19.容器类
概述 容器 就是存放数据的一个集合 (java提供了一个接口专门去约束我们容器的实现类) watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L ...
- ubuntu12.04 安装nginx+php+mysql (lnmp)的web服务器环境
1.Ubuntu12.04 安装nginx+php+mysql (lnmp)的web服务器环境 http://blog.db89.org/ubuntu12-04-install-nginx-php-m ...
- csu1326(The contest)
题目链接:传送门 题目思路:并查集加分组背包 #include <iostream> #include <cstdio> #include <cstdlib> #i ...
- poj2528
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 56864 Accepted: 16445 ...