Z0J 3772 Calculate the Function 线段树+矩阵
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235
这种题目居然没想到,一开始往矩阵快速幂想去了,因为之前跪了太多矩阵快速幂,后来就。。哎,擦。怎么没想到就是个线段树呢
因为1 A[x] * A[x-1] 这个是很容易推出的,比赛的时候看到这个就想那个快速幂去了,根本没往线段树上想,其实用线段树存储前面的矩阵,得到一个询问
1 0 A[x-2]
L R,则访问 L+2 ,R的矩阵部分提取出来,再跟A[L] A[L+1]相乘就是结果了
则建树为 nlogn,访问为mlogn,由于n和m都在10^5,所以可以承受
要注意的是矩阵不满足交换律,在这个线段树里面矩阵相乘的时候必须从大的到小的来乘。
#include <iostream>
#include <cstdio>
#include <cstring>
#define lson rt<<1,l,mid
#define rson (rt<<1|1),mid+1,r
#define N 100010
#define ll unsigned long long
using namespace std;
ll A[N],n,m;
const ll M=;
struct MAT
{
ll mat[][];
}tree[N*],E;
void init(int rt,int x)
{
tree[rt].mat[][]=tree[rt].mat[][]=;
tree[rt].mat[][]=A[x];
tree[rt].mat[][]=;
}
MAT operator *(MAT a,MAT b)
{
MAT c;
memset(c.mat,,sizeof (c.mat));
ll tmp;
for (int i=;i<;i++)
{
for (int j=;j<;j++)
{
for (int k=;k<;k++)
{
tmp=(a.mat[i][k]*b.mat[k][j])%M;
c.mat[i][j]+=tmp;
if (c.mat[i][j]>M)
c.mat[i][j]%=M;
}
}
}
return c;
}
void up(int l,int r,int rt)
{
tree[rt]=tree[rt<<|]*tree[rt<<];
}
void build(int rt,int l,int r)
{
if (l>=r)
{
init(rt,l);
return;
}
int mid=(l+r)/;
build(lson);
build(rson);
up(l,r,rt);
}
void test(int rt,int l,int r)
{
cout<<l<<" lr "<<r<<":"<<endl;
for (int i=;i<;i++)
{
for (int j=;j<;j++)
{
cout<<tree[rt].mat[i][j]<<" ";
}
cout<<endl;
}
cout<<endl; if (l>=r)
{
return;
}
int mid=(l+r)/;
test(lson);
test(rson);
}
MAT query(int L,int R,int rt,int l,int r)
{
MAT c=E;
if (L<=l && r<=R)
{
c=tree[rt];
return c;
}
int mid=(l+r)/;
if (R>mid)
c=query(L,R,rson);
if (L<=mid)
c=c*query(L,R,lson);
return c;
}
int main()
{
int t,a,b;
scanf("%d",&t);
memset(E.mat,,sizeof E.mat);
E.mat[][]=E.mat[][]=;
while (t--)
{
scanf("%llu%llu",&n,&m);
for (ll i=;i<=n;i++)
scanf("%llu",&A[i]); build(,,n);
//test(1,1,n);
for (ll i=;i<m;i++)
{
scanf("%d%d",&a,&b);
if (a>b) swap(a,b);
if (b-a<=)
{
if (b==a)
printf("%llu\n",A[a]);
else
printf("%llu\n",A[b]);
continue;
}
MAT c;
c=query(a+,b,,,n);
ll ans=((c.mat[][]*A[a+])%M)+((c.mat[][]*A[a])%M);
ans%=M;
printf("%llu\n",ans);
}
}
return ;
}
Z0J 3772 Calculate the Function 线段树+矩阵的更多相关文章
- ZOJ 3772 Calculate the Function 线段树+矩阵
Calculate the Function Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %ll ...
- ZOJ3772 - Calculate the Function(线段树+矩阵)
题目大意 给定一个序列A1 A2 .. AN 和M个查询 每个查询含有两个数 Li 和Ri. 查询定义了一个函数 Fi(x) 在区间 [Li, Ri] ∈ Z. Fi(Li) = ALi Fi(Li ...
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
- 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function
Calculate the Function Problem's Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are whit ...
- CF719E(线段树+矩阵快速幂)
题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)
线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...
- CF718C Sasha and Array 线段树+矩阵加速
正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...
随机推荐
- JS - 使 canvas 背景透明
canvas = document.getElementById('canvas1'); var context = canvas.getContext('2d');context.fillStyle ...
- 解决CSS背景模糊
.banner{ background:url(banner.jpg); -moz-background-size:100% 100%; background-size:100% 100%; }
- 19 03 02 HTTP和https
HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法. HTTPS(Hypertext Transfer Protocol ov ...
- bzoj 3696: 化合物
哦,这个困惑了我好久的东西——生成函数(母函数),(然而拿这个东西去向学文化课的同学装逼并不成功...) 生成函数,就是把原来的加法组合变成乘法的指数加法,那么我们要求的值就是相应的指数的系数的值啦, ...
- 那些年我们一起踩过的坑(javascript常见的陷阱)
1.object最后一个逗号 定义object直接量或json,最后一个逗号多写了,在ie下会报错,高级浏览器则不会,给只使用chrome调试的同学敲个警钟.踩了无数次这个坑了. 2.自动加分号 ...
- JAVA - SpringBoot项目引用MyBatis操作数据库
JAVA - SpringBoot项目引用MyBatis操作数据库 1. 创建SpringBoot项目,参考:https://www.cnblogs.com/1285026182YUAN/p/1232 ...
- Docker部署Python应用程序
Docker部署Python应用程序 1. 单个py文件部署 生成Dockerfile 文件 插件用的豆瓣的镜像,,重置时间(容器的默认时间是UTC时间与宿主机的相差8小时). 文中需要三个插件(pe ...
- 类成员之迭代iter
class B: def __init__(self,name,age): self.name = name self.age = age #创建迭代方法 def __iter__(self): re ...
- 第五篇Django URL name 详解
Django URL name 详解 利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护. Djan ...
- android 开发学习2
Dao dao = new Dao(yi_ji_lu_zhang_dan.this);List<GetOneRecord> list = dao.getAllRecord();//创建迭代 ...