这题着实是锻炼线段树的一个好题,纯模板题但是加上了一点其他的东西,细节很多
细节一:格式错误,每两个一大组数据和之间需要有有一个换行。
细节二:每两个输出之间有一个换行
细节三:每次需要清空存储矩阵的结构体(但是我不是特别明白为什么要清空)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <stack>
#include <cmath>
#define fuck() (cout << "--------------------------------" << endl)
#define MOD 1000000007
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 30000 + 10;
int mod,m,n;
struct matrix
{
long long a[2][2];
matrix()
{
a[0][0] = a[1][1] = 0;
a[1][0] = a[0][1] = 0;
}
void read()
{
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
scanf("%lld",&a[i][j]);
}
matrix operator * (const matrix &p) const
{
matrix x;
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
for(int k=0; k<2; k++)
{
x.a[j][k] += (a[j][i] * p.a[i][k] ) % mod;
x.a[j][k] %= mod;
}
return x;
}
};
matrix node[maxn],sum[maxn*4];
void build(int o, int l, int r)
{
if(l == r)
{
sum[o] = node[l];
return;
}
int m = (l+r)/2;
build(o*2, l, m);
build(o*2+1, m+1, r);
sum[o] = sum[o*2] * sum[o*2+1];
}
matrix query(int o, int l, int r, int ql, int qr)
{
if(ql <= l && qr >= r)
{
return sum[o];
}
int m = (l+r)/2;
matrix x;
x.a[1][1] = x.a[0][0] = 1;
x.a[1][0] = x.a[0][1] = 0;
if(ql <= m) x = x * query(2*o, l, m, ql, qr);
if(qr > m) x = x * query(2*o+1, m+1, r, ql, qr);
return x;
}
int main()
{
bool flag = true;
while(scanf("%d%d%d",&mod,&n,&m) == 3)
{
if(!flag) printf("\n");
flag = false;
for(int i=1; i<=n; i++)
node[i].read();
build(1,1,n);
for(int k=0; k<m; k++)
{
int ll,rr;
scanf("%d%d",&ll,&rr);
matrix ans = query(1,1,n,ll,rr);
if(k) printf("\n");
for(int i=0; i<2; i++)
{
for(int j=0; j<2; j++)
{
if(!j) printf("%lld",ans.a[i][j]);
else printf(" %lld\n",ans.a[i][j]);
}
}
}
}
}