zoukankan      html  css  js  c++  java
  • 【JSOI2017】 预言(广义常系数齐次线性递推)

    https://gmoj.net/senior/#main/show/100013

    考虑(mle 100)的部分分,不难想到矩阵乘法。

    这里,把(and)定义乘法,(xor)定义为加法,然后做正常的矩阵乘法。

    发现这个东西和常系数齐次线性递推很像。

    常系数齐次线性递推是(Mod)一个多项式(M),这里我们也可以定义这么一个类似的多项式。

    虽然(and)乘法没有逆运算,但是注意到每次除的都是(M)最高项,最高项系数(=2^{32}-1),任何一个数除以这个数得到自己,那么就没有问题了。

    时间复杂度:(O(n^2~log~m))

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int N = 2e3 + 5;
    
    #define ui unsigned int
    
    int n; ll m;
    ui a[N], b[N];
    
    const ui inf = 4294967295ll;
    
    void qmo(ui *a) {
    	fd(i, 2 * n, n + 1) if(a[i]) {
    		fo(j, 1, n) a[i - j] ^= b[j] & a[i];
    		a[i] = 0;
    	}
    }
    ui c[N];
    void mul(ui *a, ui *b) {
    	fo(i, 0, 2 * n) c[i] = 0;
    	fo(i, 0, n) fo(j, 0, n) c[i + j] ^= a[i] & b[j];
    	qmo(c);
    	fo(i, 0, n) a[i] = c[i];
    }
    
    ui s[N], x[N];
    
    int main() {
    	freopen("prophecy.in", "r", stdin);
    	freopen("prophecy.out", "w", stdout);
    	scanf("%d", &n);
    	fo(i, 1, n) scanf("%u", &a[i]);
    	fo(i, 1, n) scanf("%u", &b[i]);
    	scanf("%lld", &m);
    	s[0] = inf; x[1] = inf;
    	for(; m; m /= 2, mul(x, x))
    		if(m & 1) mul(s, x);
    	ui ans = 0;
    	fo(i, 1, n) ans ^= s[i] & a[i];
    	pp("%u
    ", ans);
    }
    
    
  • 相关阅读:
    二分图的判定 (图)
    并查集(模板)
    数独 (dfs)
    Map <STL>
    Set <STL>
    二叉搜索树的实现
    Find a way (BFS)
    根据输入的变量,执行相应的计算公式并返回结果
    检测字符串当中x与o的数目是否相等
    根据给定的数字和字符串,生成循环指定次数的字符串
  • 原文地址:https://www.cnblogs.com/coldchair/p/12743500.html
Copyright © 2011-2022 走看看