http://codeforces.com/problemset/problem/300/D

题意:每一次操作可以选一个正方形,令边长为n,如果n为奇数那么可以从中间画一个十字,分成4个大小相等的边长为(n-1)/2的正方形。给一个正方形,求操作k次后能得到的不同图案的个数

思路:令f(s,k)表示边长为s的正方形操作k次后的答案总数,则f(s,k)=∑f(s/2,k1)*f(s/2,k2)*f(s/2,k3)*f(s/2,k4),其中s为奇数,k1+k2+k3+k4=k-1,令g(s,k)=Σf(s,k1)*f(s,k2),其中s为奇数,k1+k2=k。那么有f(s,k)=Σg(s/2,k')*g(s/2,k-1-k'),g(s,k)=Σf(s,k')*f(s,k-k'),其中s为奇数,k'取遍所有可能的值。由于s最多递归logs层,所以用一个不超过logs的数和k表示状态即可,然后递推计算,复杂度O(k2logs)。

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; //#ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
//#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
template<typename T>
void V2A(T a[],const vector<T>&b){for(int i=;i<b.size();i++)a[i]=b[i];}
template<typename T>
void A2V(vector<T>&a,const T b[]){for(int i=;i<a.size();i++)a[i]=b[i];} const double PI = acos(-1.0);
const int INF = 1e9 + ;
const double EPS = 1e-8; /* -------------------------------------------------------------------------------- */ template<int mod>
struct ModInt {
const static int MD = mod;
int x;
ModInt(ll x = ): x(x % MD) {}
int get() { return x; } ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD? x0 : x0 - MD); }
ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD? x0 + MD : x0); }
ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
ModInt operator / (const ModInt &that) const { return *this * that.inverse(); } ModInt operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
ModInt operator -= (const ModInt &that) { x -= that.x; if (x < ) x += MD; }
ModInt operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
ModInt operator /= (const ModInt &that) { *this = *this / that; } ModInt inverse() const {
int a = x, b = MD, u = , v = ;
while(b) {
int t = a / b;
a -= t * b; std::swap(a, b);
u -= t * v; std::swap(u, v);
}
if(u < ) u += MD;
return u;
} };
typedef ModInt<> mint; mint dp[][], f[][]; void pre_init() {
for (int i = ; i <= ; i ++) dp[i][] = f[i][] = ;
for (int i = ; i <= ; i ++) {
dp[i][] = ;
f[i][] = ;
for (int j = ; j <= ; j ++) {
for (int k = ; k <= j; k ++) {
dp[i][j] += f[i - ][k] * f[i - ][j - k - ];
}
for (int k = ; k <= j; k ++) {
f[i][j] += dp[i][k] * dp[i][j - k];
}
}
}
} int work(int n, int k) {
if (k == ) return ;
int p = ;
while (n & ) {
p ++;
n = (n - ) / ;
}
if (n) p ++;
return dp[p][k].get();
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n, T, k;
pre_init();
while (cin >> T) {
while (T --) {
scanf("%d%d", &n, &k);
printf("%d\n", work(n, k));
}
}
return ;
}

[CodeForces 300D Painting Square]DP的更多相关文章

  1. CF300D Painting Square

    Painting Square https://codeforces.com/problemset/problem/300/D 给了一个理解起来较复杂但是本质上很简单的分形. 题解 很显然,只有边长为 ...

  2. Codeforces 828B Black Square(简单题)

    Codeforces 828B Black Square(简单题) Description Polycarp has a checkered sheet of paper of size n × m. ...

  3. [Codeforces 1201D]Treasure Hunting(DP)

    [Codeforces 1201D]Treasure Hunting(DP) 题面 有一个n*m的方格,方格上有k个宝藏,一个人从(1,1)出发,可以向左或者向右走,但不能向下走.给出q个列,在这些列 ...

  4. Codeforces - 1198D - Rectangle Painting 1 - dp

    https://codeforces.com/contest/1198/problem/D 原来是dp的思路,而且是每次切成两半向下递归.好像在哪里见过类似的,貌似是紫书的样子. 再想想好像就很显然的 ...

  5. Educational Codeforces Round 67 E.Tree Painting (树形dp)

    题目链接 题意:给你一棵无根树,每次你可以选择一个点从白点变成黑点(除第一个点外别的点都要和黑点相邻),变成黑点后可以获得一个权值(白点组成连通块的大小) 问怎么使权值最大 思路:首先,一但根确定了, ...

  6. Codeforces 840C 题解(DP+组合数学)

    题面 传送门:http://codeforces.com/problemset/problem/840/C C. On the Bench time limit per test2 seconds m ...

  7. codeforces Hill Number 数位dp

    http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits:  5000 MS   Memory Limits: ...

  8. codeforces Educational Codeforces Round 16-E(DP)

    题目链接:http://codeforces.com/contest/710/problem/E 题意:开始文本为空,可以选择话费时间x输入或删除一个字符,也可以选择复制并粘贴一串字符(即长度变为两倍 ...

  9. codeforces #round363 div2.C-Vacations (DP)

    题目链接:http://codeforces.com/contest/699/problem/C dp[i][j]表示第i天做事情j所得到最小的假期,j=0,1,2. #include<bits ...

随机推荐

  1. 关于JS垃圾回收机制

    一.垃圾回收机制的必要性 由于字符串.对象和数组没有固定大小,所以当它们的大小已知时,才能对它们进行动态的存储分配.JavaScript程序每次创建字符串.数组或对象时,解释器都必须分配内存来存储那个 ...

  2. vue使用trackingjs

    前言:因为公司是做人工智能-AI的,所有一个web数据平台为了装X,需要做个人脸登陆.前台需要把人脸的base64发给后台去做人脸校验. 功能很简单,需要注意的是web需要实现“调用摄像头”和“自动拍 ...

  3. 不借助多余参数也可交换两个参数(c++,swap函数)

    利用a^a=0异或属性 [示例代码] #include<stdio.h> void data_swap(int &a,int &b){ a = a ^ b; b = a ^ ...

  4. Java中基础类基础方法(学生类)(手机类)

    学生类: //这是我的学生类class Student { //定义变量 //姓名 String name; //null //年龄 int age; //0 //地址 String address; ...

  5. Go gRPC进阶-gRPC转换HTTP(十)

    前言 我们通常把RPC用作内部通信,而使用Restful Api进行外部通信.为了避免写两套应用,我们使用grpc-gateway把gRPC转成HTTP.服务接收到HTTP请求后,grpc-gatew ...

  6. Web前端三大主流框架是什么?Web前端前景与就业形势

    近十年以来,IT行业发展火热,衍生了很多新职业,例如UI设计师.开发工程师.软件测试工程师等等,在众多备受瞩目的新生职业中,Web前端工程师是其中的一员.那么Web前端三大主流框架是什么呢? 一.We ...

  7. gin请求数据校验

    前言 最近优化gin+vue的前后端分离项目代码时候,发现代码中对请求数据的校验比较繁琐,于是想办法简化它.最终我发现了go-playground/validator开源库很好用. 优化前代码 代码如 ...

  8. 4.K均值算法应用

    一.课堂练习 from sklearn.cluster import KMeans import matplotlib.pyplot as plt import numpy as np from sk ...

  9. 2019-2020-1 20199310《Linux内核原理与分析》第六周作业

    1.问题描述 在前面的文章中,学习了系统调用的相关理论知识,并使用库函数API和C代码中嵌入汇编代码两种方式使用getpid()系统调用.本文将内容围绕系统调用system_call的处理过程,在Me ...

  10. java学习(第二篇)语法学习

    1.java标识符 类名.变量名以及方法名都被称为标识符. 关于 Java 标识符,有以下几点需要注意: 所有的标识符都应该以字母(A-Z 或者 a-z),美元符($).或者下划线(_)开始 首字符之 ...