您的位置:首页 > 其它

【HDU5068】Harry And Math Teacher

2017-12-04 15:02 288 查看
题目链接:传送门

题解:

新姿势

线段树维护区间矩阵乘法

//by sdfzchy
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define gmid int mid=(l+r)>>1
#define L(x) ((x)<<1)
#define R(x) ((x)<<1|1)
using namespace std;
typedef long long LL;
const int inf=(1<<30),N=100010,mod=1e9+7;
int n,m;
inline int in()
{
char ch=getchar();
int f=1,tmp=0;
while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {tmp=(tmp<<1)+(tmp<<3)+(ch-'0');ch=getchar();}
return tmp*f;
}

bool ok
[2][2];

struct Matrix
{
LL a[2][2];
Matrix() {memset(a,0,sizeof(a));}
Matrix operator *(const Matrix &A) const
{
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.a[i][j]=(c.a[i][j]+a[i][k]*A.a[k][j])%mod;
return c;
}
}t[N*4+5];

void pushup(int rt) {t[rt]=t[L(rt)]*t[R(rt)];}

void build(int l,int r,int rt)
{
if(l==r)
{
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
t[rt].a[i][j]=1;
return;
}
gmid;
build(lson);
build(rson);
pushup(rt);
}

void update(int pos,int y,int z,int l,int r,int rt)
{
if(l==r) {t[rt].a[y][z]^=1;return;}
gmid;
if(pos<=mid) update(pos,y,z,lson);
else update(pos,y,z,rson);
pushup(rt);
}

Matrix ans;
Matrix query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r) return t[rt];
gmid;
if(L>mid) return query(L,R,rson);
if(R<=mid) return query(L,R,lson);
return query(L,mid,lson)*query(mid+1,R,rson);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
build(1,n-1,1);
int op,x,y,z;
while(m--)
{
op=in();x=in(),y=in();
if(!op)
{
LL tmp=0;
ans=query(x,y-1,1,n-1,1);
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
tmp+=ans.a[i][j];
printf("%lld\n",tmp%mod);
}
else z=in(),update(x,y-1,z-1,1,n-1,1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: