Codeforces 691E Xor-sequences(思维)

题目链接 Xor-sequences

利用矩阵加速。

先预处理出当序列长度为2的时候的方案数。

也就是说这个序列起点是a[i]终点是a[j]且中间没有任何元素。

但是所求的k很大,序列长度远远不止2。这个时候就要考虑乘法原理。

然后利用矩阵乘法来模拟乘法原理,那么就用到了矩阵快速幂。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)              for(int i(a); i <= (b); ++i)

struct Matrix{ long long  arr[105][105];}  init, unit;
long long k, ret, mod = 1e9 + 7;
long long a[105];
int n;

Matrix Mul(Matrix a, Matrix b){
    Matrix c;
    rep(i, 1, n) rep(j, 1, n){
        c.arr[i][j] = 0;
        rep(k, 1, n) (c.arr[i][j] += (a.arr[i][k] * b.arr[k][j] % mod)) %= mod;
    }
    return c;
}

Matrix Pow(Matrix a, long long  k){
    Matrix ret(unit); for (; k; k >>= 1, a = Mul(a, a)) if (k & 1) ret = Mul(ret, a); return ret;
}    

inline long long check(long long x){
    int ret = 0;
    for (; x; x >>= 1) ret += (x & 1);
    return ret % 3 == 0;
}

int main(){

    scanf("%d%lld", &n, &k);
    rep(i, 1, n) unit.arr[i][i] = 1;
    rep(i, 1, n) scanf("%lld", a + i);
    rep(i, 1, n) rep(j, 1, n) init.arr[i][j] = check(a[i] ^ a[j]);
    Matrix Ans = Pow(init, k - 1); ret = 0;
    rep(i, 1, n) rep(j, 1, n) (ret += Ans.arr[i][j]) %= mod;
    printf("%lld\n", ret);

    return 0;

}
时间: 2024-11-03 22:35:44

Codeforces 691E Xor-sequences(思维)的相关文章

Xor-sequences CodeForces - 691E || 矩阵快速幂

Xor-sequences CodeForces - 691E 题意:在有n个数的数列中选k个数(可以重复选,可以不按顺序)形成一个数列,使得任意相邻两个数异或的结果转换成二进制后其中1的个数是三的倍数.求可能形成的不同数列个数(只要选出的数列中,任意两个元素在原序列中的位置不同,就算作不同的序列,比如在原数列[1,1]中选1个,那么第一个1和第二个1要分开算). 方法: 很容易列出dp方程: dp[k][i]表示取了k个,最后一个在第i位.a[i][j]表示i和j异或结果转换成二进制后1的个数

CodeForces 288C - Polo the Penguin and XOR operation(思维)

题意: 就是让你构造一个序列,使得序列异或和最大,序列为n 的全排列 ,序列和计算方式为   SUM  =   a[1] ^ 0 + a[2] ^ 1 + a[3] ^ 2 + .......a[n] ^ n 构造出一个序列使得和最大 题解: 策略为使得每次异或出来的结果的1尽可能多,而优先从最大的n  开始考虑,因为n  最有可能出更大的数字 代码: #include<stdio.h> #include<string.h> int Ans[1000005]; int main()

CodeForces 373B Making Sequences is Fun

Making Sequences is Fun Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 373B Description We'll define S(n) for positive integer n as follows: the number of the n's digits in the decimal

CodeForces 1102C-简单的思维题

题目链接:http://codeforces.com/problemset/problem/1102/C C. Doors Breaking and Repairing time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You are policeman and you are playing a game with Slavik

CodeForces 789D 欧拉路径计数,思维

CodeForces 789D 题意:n个点m条边的无向图,求经过其中m-2条边两次,剩下2条边一次的方案数有几种,如果剩下两条边的集合一样算同一种. tags: 选出两条边,其它m-2条边假想复制成两条,这样就是要求欧拉路径是否存在,即奇点个数是否为0或2. 所以该怎么选这两条边呢? 先把边分为自环边和普通边. 1.选取两条不相邻普通边,图中存在4个奇点,不满足欧拉路径条件: 2.选取两条相邻普通边,图中存在2个奇点,满足欧拉路径条件: 3.选取一条普通边一条自环,图中存在2个奇点,满足欧拉路

Codeforces 627A XOR Equation(思路)

题目大概说两个正整数a.b,已知s=a+b以及x=a xor b的值,问有几种a.b这样的数对. 我知道异或相当于无进位的加法,s-x就是其各个位置的进位,比如s-x=1010,那就表示a和b的第1位和第3位发生的进位. 这样,对于某些位其值就能确定,对于有些位其值不能确定(该位xor和为1且没有发生进位),这时a和b的该位都能选择0或者1,对于不确定的就是乘法原理答案累乘2. 另外还有一些情况是不可能的,首先s<x不可能,s-x是奇数不可能,某一位xor和是1且发生了进位这不可能. 最后注意是

CodeForces 789E bfs建模,思维

CodeForces 789E 题意:有k种可乐,每种的测试为ai/1000. 要你合成一种浓度为n/1000的可乐,问最小要杯可乐,每种可乐可重复取. tags:  要注意到浓度绝不会超过1000/1000. 假设选取m杯可乐,则 (a1+a2+......+am) / m = n,变换一下为(a1-n)+(a2-n)+......+(am-n) = 0.即要选 m杯可乐,其浓度减 n之和为0.而浓度不超过1000,故(a1-n)+(a2-n)+....+(as-n)的和肯定在 -1000~1

codeforces 242E. XOR on Segment 线段树

题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵线段树就可以. 每一次异或, 对于给定的x, 如果x的第i位是1, 那么就将第i棵线段树在给定的区间内0,1翻转, 这是很基础的操作. 对于区间求和操作, 我们可以求出给定的区间, 从高位到低位, 每一位依次有多少个1, 然后就可以直接求出来, 感觉不好表达....具体看代码. 1 #include

2017-03-16 Codeforces 453A 概率期望,思维 UOJ 228(待补)

Codeforces 453A   A. Little Pony and Expected Maximum 题意:一个m面质地均匀的骰子,每面出现的概率都是独立的1/m, 你需要投掷n次,其结果是这n次出现的最大点数.问投掷n次骰子的结果的期望值是多少,要求相对误差或绝对误差不超过1e-4. tags:枚举骰子出现最大值i,计算出最大值为i时的概率,就得到了答案. 最大值为i的概率=(i/m)^n-((i-1)/m)^n. #include<bits/stdc++.h> using names