转载请注明出处,谢谢http://blog.youkuaiyun.com/ACM_cxlove?viewmode=contents by---cxlove
题目:给出一个序列,初始为0。
其中将每个数调整成1,2,3中的一个,但是有一些要求(ai,ai+1)必须是合法的,矩阵给出
每一个询问,其中有一位的数字是确定的
维护一个线段树,每个节点有一个矩阵a[i][j]表示这个区间的第一个数是i,最后一个是j的数目有多少。
那么初始化的时候,对于叶子,便是a[i][j]=(i==j?1:0)3种情况都有可能
然后向上更新,则需要枚举父亲的两端,然后枚举子节点的另外两端,判断两个内侧相邻是否合法即可。
那么对于每一次查询,则去更新叶子结点
如果该位要求是0,则说明无要求,和初始化一样
否则则将指定的a[i][i]=1。
结果的话便是根结点的值的和
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<set>
#include<string>
#include<queue>
#define inf 1600005
#define M 40
#define N 80000
#define maxn 2000005
#define eps 1e-7
#define zero(a) fabs(a)<eps
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define MOD 777777777
#define lson step<<1
#define rson step<<1|1
#define sqr(a) ((a)*(a))
#define Key_value ch[ch[root][1]][0]
#define test puts("OK");
#define pi acos(-1.0)
#define lowbit(x) ((x)&(-(x)))
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define vi vector<int>
using namespace std;
int ok[3][3],n,m;
struct Seg_Tree{
int left,right;
LL a[3][3];
}L[N*4];
void Push_Up(int step){
for(int i=0;i<3;i++)
for(int j=0;j<3;j++){
L[step].a[i][j]=0;
for(int k=0;k<3;k++)
for(int r=0;r<3;r++){
if(!ok[k][r]) continue;
L[step].a[i][j]=(L[step].a[i][j]+(LL)L[lson].a[i][k]*L[rson].a[r][j])%MOD;
}
}
}
void Bulid(int step,int l,int r){
L[step].left=l;
L[step].right=r;
if(l==r){
mem(L[step].a,0);
for(int i=0;i<3;i++)
L[step].a[i][i]=1;
return ;
}
int m=(l+r)>>1;
Bulid(lson,l,m);
Bulid(rson,m+1,r);
Push_Up(step);
}
void Update(int step,int pos,int num){
if(L[step].left==pos&&pos==L[step].right){
mem(L[step].a,0);
if(num==-1){
for(int i=0;i<3;i++)
L[step].a[i][i]=1;
}
else L[step].a[num][num]=1;
return ;
}
int m=(L[step].left+L[step].right)/2;
if(pos<=m) Update(lson,pos,num);
else Update(rson,pos,num);
Push_Up(step);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
scanf("%d",&ok[i][j]);
Bulid(1,1,n);
while(m--){
int pos,num;
scanf("%d%d",&pos,&num);
Update(1,pos,num-1);
LL ans=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
ans=(ans+L[1].a[i][j])%MOD;
printf("%I64d\n",ans);
}
return 0;
}