宣传墙

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

ALPHA 小镇风景美丽,道路整齐,干净,到此旅游的游客特别多。CBA 镇长准备在一条道路南 面 4*N 的墙上做一系列的宣传。为了统一规划,CBA 镇长要求每个宣传栏只能占相邻的两个方格 位置。但这条道路被另一条道路分割成左右两段。CBA 镇长想知道,若每个位置都贴上宣传栏, 左右两段各有有多少种不同的张贴方案。 例如: N=6,M=3, K=2, 左,右边各有 5 种不同的张贴方案


输入
第一行: T 表示以下有 T 组测试数据 ( 1≤T ≤8 )
接下来有T行, 每行三个正整数 N M K 分别表示道路的长度,另一条道路的起点和宽度
(1≤ N ,M ≤ 1 000 000, 1≤ K ≤ 100000)
输出
每组测试数据,输出占一行:两个整数,分别表示左右两段不同的张贴方案数。由于方案总数
可能很大,请输出对 997 取模后的结果。
样例输入
2
6 3 2
5 3 2
样例输出
5 5
5 1
来源
河南省第九届省赛
上传者
onlinejudge
N高达100w,继续使用前面做这个题目直接状压DP得话复杂度太高(16*16*100w),再算上常数..显然会TLE
这时候引入了矩阵的概念...总感觉莫名其妙的虽然会用但是自己没想到要这样子写
我们在dp时dp[cur][S]得值由dp[last][S]决定,那么由哪些决定呢,last中的某些状态如果能与cur中的某个状态相容,我们就把last中这些满足匹配条件的
状态的方案数得和赋值给cur中的这个状态,一轮结束之后再由这个方法推cur+1的状态,最后的答案来自于dp[N][(1<<N)-1]
仔细观察,如果对于矩阵运算熟悉得话可能会自然而然的联系到这里,cur由last决定相当于让last中的每一项乘以一个1/0,显然匹配时乘1不匹配就是0喽,
转换一下思路我们就是让last数组运算了N(所有状态个数)次,每一次都是SUM(last[i]*(1/0)),然后将这个SUM赋值给cur对应的状态
其实不就是两个矩阵进行了一次乘的操作吗last为一个1*N的矩阵,1/0为一个N*N的关系矩阵,设这个关系矩阵为e,则e[i][j]==1表示状态i与j相容,反之相斥。
每次运算时关系矩阵并不会改变,因此就是在求这个关系矩阵的幂,利用矩阵快速幂求知即可。
为了方便我们把cur==0时的行向量表示为(0,0,0,......1)
这样对于一个询问M,我们只要求关系矩阵的N次方,答案就是a[maxn][maxn];
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define high ((1<<4)-1)
#define MOD 997
int e[20][20];
int fir[20];
bool check(int x,int i)
{  return x&(1<<i); }
int comp(int A,int B,int N)
{
 int i=0,j,k;
 while(i<N){
    if(!check(A,i)){
        if(!check(B,i)) return 0;
        i++;
    }
    else{
        if(!check(B,i)) i++;
        else {
            if(i==N-1||!check(A,i+1)||!(check(A,i+1)&&check(B,i+1))) return 0;
            else i+=2;
        }
    }
 }
 return 1;
}
void init()
{
    int i,j,k;
    for(i=0;i<=high;++i){
        for(j=0;j<=high;++j){
            e[i][j]=comp(j,i,4);
        }
    }
    for(i=0;i<=high;++i) fir[i]=1;
}
struct Martix
{
    int a[18][18];
    Martix(){memset(a,0,sizeof(a));}
};

Martix mul(Martix A,Martix B)
{
    Martix tmp;
    int i,j,k;
    for(i=0;i<=15;i++){
        for(k=0;k<=15;++k){
            for(j=0;j<=15;++j){
                tmp.a[i][j]+=A.a[i][k]*B.a[k][j];
                tmp.a[i][j]%=997;
            }
        }
    }
    return tmp;
}

Martix qpow(Martix tmp,int num)
{
    Martix res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0; i<16; i++) res.a[i][i]=1;
    while(num)
    {
        if(num&1) res=mul(res,tmp);
        tmp=mul(tmp,tmp);
        num>>=1;
    }
    return res;
}
int solve(int N)
{
    Martix ans;
    for(int i=0;i<=15;++i){
        for(int j=0;j<=15;++j){
            ans.a[i][j]=e[i][j];
        }
    }
    ans=qpow(ans,N);
    int p=0;
    return ans.a[15][15];
}
int main()
{
    int N,M,K,i,j,k,t;
    init();
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&N,&M,&K);
        printf("%d %d\n",solve(M-1),solve(N-(M+K-1)));
    }
    return 0;
}

nyoj1273 河南省第九届省赛_"宣传墙"、状压DP+矩阵幂加速的更多相关文章

  1. NYOJ--1276--机器设备(河南省第九届省赛,简单的bfs)

    机器设备 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 Alpha 公司设计出一种节能的机器设备.它的内部结构是由 N 个齿轮组成.整个机器设备有 一个驱动齿轮,当 ...

  2. 2019年第十届蓝桥杯省赛-糖果(一维状压dp)

    看到20的数据量很容易想到状压dp. 开1<<20大小的数组来记录状态,枚举n个糖包,将其放入不同状态中(类似01背包思想) 时间复杂度O(n*(2^20)). import java.u ...

  3. 【noip模拟赛5】细菌 状压dp

    [noip模拟赛5]细菌   描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...

  4. 南京网络赛E-AC Challenge【状压dp】

    Dlsj is competing in a contest with n (0 < n \le 20)n(0<n≤20) problems. And he knows the answe ...

  5. 【CSP模拟赛】Adore(状压dp 二进制)

    题目描述 小w偶然间见到了一个DAG.这个DAG有m层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k个节点.现在小w每次可以取反第i(1<i<n-1)层和第i+1层之间的连 ...

  6. 河南省acm第九届省赛--《表达式求值》--栈和后缀表达式的变形--手速题

    表达式求值 时间限制:1000 ms | 内存限制:65535 KB 难度:3   描述 假设表达式定义为:1. 一个十进制的正整数 X 是一个表达式.2. 如果 X 和 Y 是 表达式,则 X+Y, ...

  7. NYOJ 1272 表达式求值 第九届省赛 (字符串处理)

    title: 表达式求值 第九届省赛 nyoj 1272 tags: [栈,数据结构] 题目链接 描述 假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式. 2. 如果 X 和 Y 是 表 ...

  8. BZOJ_2734_[HNOI2012]集合选数_构造+状压DP

    BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...

  9. BZOJ_1076_[SCOI2008]奖励关_状压DP

    BZOJ_1076_[SCOI2008]奖励关_状压DP 题意: 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛 ...

随机推荐

  1. ZOJ 3469Food Delivery(区间DP)

    Food Delivery Time Limit: 2 Seconds      Memory Limit: 65536 KB When we are focusing on solving prob ...

  2. 导出Excel过程中遇到的问题java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlException

    尝试实现java导出功能时遇到如下报错: org.apache.jasper.JasperException: javax.servlet.ServletException: java.lang.No ...

  3. Max Sum Plus Plus---hdu1024(动态规划求M段的最大和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 题意就是有n个数分成m段,求最大的和: dp[i][j]表示把 j 个数分成 i 段,选择第 j ...

  4. 【Linux】通过top语句可以查看压力测试的实时服务器状态。(可以通过百度Linux top查看相关内容)

    Linux实时查看服务器状态的两个语句 1.显示基本服务器监控状态语句如下:linux top 在这里输入 主要先看服务器负载高不高,高了后能否降下来,再看网络,io,数据库状态. 是有一个工具可以监 ...

  5. Openstack(十五)快速添加新计算节点

    当后期添加新物理服务器作为计算节点,如果按照上面的过程安装配置的话会非常的慢,但是可以通过复制配置文件的方式快速添加. 15.1计算节点服务安装 #提前将yum仓库.防火墙.selinux.主机名.时 ...

  6. C# 使用BackgroundWorker实现WinForm异步

    写了一个基于BackgorundWorker演示异步操作的例子.由于这个理基本上实现了BackgorundWorker的大部分功能:异步操作的启动.操作结束后的回调.异步操作的撤销和进度报告等等.尽管 ...

  7. vim多行注释和取消注释 Ubuntu

    多行注释: 1. 进入命令行模式,按ctrl + v进入 visual block模式,然后按d 是选择到最后一行,也可以直接光标上下左右,把需要注释的行标记起来 2. 按大写字母I,再插入注释符,例 ...

  8. CCPC2018-湖南全国邀请赛 Solution

    A - Easy $h$-index 后缀扫一下 #include <bits/stdc++.h> using namespace std; #define ll long long #d ...

  9. MFC中利用GDI+进行双缓冲作图的有关设置

    这里只是在遇到实际问题的时候提出的一种解决方法,用以处理闪屏问题. 首先要做的是对GDI的一个设置问题: 在应用程序类中添加一个保护权限数据成员 class C...App: {... private ...

  10. SQL: coalesce()函数

    ①用途: 将空值替换成其他值 返回第一个非空值 ②表达式: COALESCE是一个函数, (expression_1, expression_2, ...,expression_n)依次参考各参数表达 ...