题目传送门:https://agc013.contest.atcoder.jp/tasks/agc013_e

题目大意:

给定一个长度为\(n\)的木板,木板上有\(m\)个标记点,距离木板左端点的距离分别为\(X_i\),现在你需要在木板上放置一些不相交正方形,正方形需要满足

  • 正方形的边长为整数
  • 正方形底面需要紧贴木板
  • 正方形不能超出木板,正方形要将所有的木板覆盖
  • 标记点的位置不能是两个正方形的交界处

一种合法的正方形放置方案的贡献为所有正方形面积的乘积,也就是为\(\prod\limits_{i=1}^k a_i^2\),\(a_i\)为正方形的边长

请你求出所有合法方案的贡献之和,答案对\(10^9+7\)取模


这题主要难在如何转化题意,假定我们已经得到了一个合法的正方形放置方案,该如何求贡献?我们可以在正方形内放置两个标记,标记是无序的,且标记可以重叠,那么所有合法的标记摆放方案即为贡献

按照这个思路,我们可以设\(f[x][k]\)表示现在处理到第\(x\)个位置,第\(x\)个位置所在的正方形内有\(k\)个标记,这样复杂度是\(O(N)\)的,我们可以用矩乘优化到\(O(M\log N)\)

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
int x=0,f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline int read(){
int x=0,f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
const int N=1e5,p=1e9+7;
const int A[3][3]={
{1,2,1},
{0,1,1},
{1,2,2},
};
const int B[3][3]={
{1,2,1},
{0,1,1},
{0,0,1},
};
struct Matrix{
int v[3][3];
Matrix(){memset(v,0,sizeof(v));}
void clear(){memset(v,0,sizeof(v));}
void init(){for (int i=0;i<3;i++) v[i][i]=1;}
}trans,Ans,T;
Matrix operator *(const Matrix &x,const Matrix &y){
Matrix z;
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
for (int k=0;k<3;k++)
z.v[i][k]=(z.v[i][k]+1ll*x.v[i][j]*y.v[j][k])%p;
return z;
}
Matrix mlt(Matrix a,int b){
Matrix res; res.init();
for (;b;b>>=1,a=a*a) if (b&1) res=res*a;
return res;
}
int val[N+10];
int main(){
int n=read(),m=read(),Last=0;
memcpy(T.v,B,sizeof(B));
memcpy(trans.v,A,sizeof(A));
Ans.v[0][0]=1;
Ans=Ans*trans,Last=1;
for (int i=1;i<=m;i++){
int x=read();
Ans=Ans*mlt(trans,x-Last);
Ans=Ans*T,Last=x+1;
}
Ans=Ans*mlt(trans,n-Last);
printf("%d\n",Ans.v[0][2]);
return 0;
}

AtCoder Grand Contest 013 E - Placing Squares的更多相关文章

  1. Atcoder Grand Contest 013 E - Placing Squares(组合意义转化+矩阵快速幂/代数推导,思维题)

    Atcoder 题面传送门 & 洛谷题面传送门 这是一道难度 Cu 的 AGC E,碰到这种思维题我只能说:not for me,thx 然鹅似乎 ycx 把题看错了? 首先这个平方与乘法比较 ...

  2. AtCoder Grand Contest 013 C:Ants on a Circle

    题目传送门:https://agc013.contest.atcoder.jp/tasks/agc013_c 题目翻译 给你一个周长为\(L\)的圆,有\(N\)只蚂蚁在圆上爬,速度为一单位距离每秒. ...

  3. AtCoder Grand Contest 013

    这场打得蛮菜的,很晚才出BC,还一堆罚时…… A - Sorted Arrays 题目大意:将给定数列划分成单调不增或单调不减的区间,求最少区间数. 贪心即可. #include<cstdio& ...

  4. AtCoder Grand Contest 013 C :Ants on a Circle

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. AtCoder Grand Contest 013题解

    传送门 \(A\) 先把相同的缩一起,然后贪心就可以了 //quming #include<bits/stdc++.h> #define R register #define fp(i,a ...

  6. 【agc013d】AtCoder Grand Contest 013 D - Piling Up

    题意 盒子里有n块砖,每块的颜色可能为蓝色或红色. 执行m次三步操作: 1.从盒子里随便拿走一块砖 2.放入一块蓝砖和红砖到盒子里 3.从盒子里随便拿走一块砖 给定n,m 问拿出来的砖,可能有多少种不 ...

  7. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  8. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  9. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

随机推荐

  1. mac下Tomcat的安装

    转自:http://blog.csdn.net/liuyuyefz/article/details/8072485 对于Apache Tomcat 估计很多童鞋都会,那么今天就简单说下在mac上进行t ...

  2. directdraw 显示yuv

    http://www.cnblogs.com/lidan/archive/2012/03/23/2413772.html http://www.yirendai.com/msd/

  3. OpenGL之路(五)制作旋转飞机模型

    #include <gl/glut.h> #include <gl/GLU.h> #include <gl/GL.h> #pragma comment(lib, & ...

  4. 在MVC中使用泛型仓储模式和工作单元来进行增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  5. C++的string连接(a = a + b 与 a += b)

    大一学习C语言的时候,书上就写着a = a + b与 a += b等价,但是提倡用后者. 在CSDN上也看到一个关于a+=b和a=a+b的区别的帖子,大概内容如下:------------------ ...

  6. babel的安装和使用方法

    要使用Babel, 我们需要nodeJS的环境和npm, 主要安装了nodeJS, npm就默认安装了 , 现在安装nodeJS很简单了, 直接下载安装就好了: 安装es-checker 在使用Bab ...

  7. 并不对劲的bzoj5415:loj2718:uoj393:p4768:[NOI2018]归程

    题目大意 \(n\)(\(n\leq2*10^5\))个点,\(m\)(\(m\leq4*10^5\))条边的图,每条边有海拔\(a_i(a_i\leq10^9)\).长度\(l_i(l_i\leq1 ...

  8. SPOJ:Ada and Orange Tree (LCA+Bitset)

    Ada the Ladybug lives near an orange tree. Instead of reading books, she investigates the oranges. T ...

  9. wireshark分析ssl协议

    1.什么是ssl SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种 ...

  10. 【Codeforces 632D】 Longest Subsequence

    [题目链接] 点击打开链接 [算法] 设取的所有数都是k的约数,则这些数的lcm必然不大于k. 对于[1, m]中的每个数,统计a中有多少个数是它的约数即可. [代码] #include<bit ...