标签:mem size ora inline lines with define problem inf
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)
#include<bits/stdc++.h> using namespace std; #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; typedef unsigned long long ULL; const long long INF = 1e18+1LL; const double pi = acos(-1.0); const int N=5e5+20,M=1e6+10,inf=2147483647; inline LL read(){ LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } const LL mod = 1e9+7; char s[N]; struct Matix { LL arr[3][3]; }E,F,again,EE; inline Matix mul(Matix a,Matix b) { Matix ans; memset(ans.arr,0,sizeof(ans.arr)); for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { for(int k = 0; k < 3; k++) ans.arr[i][j] += a.arr[i][k] * b.arr[k][j],ans.arr[i][j] %= mod; } } return ans; } Matix v[N * 4],now,facE[N],facF[N]; int lazy[N * 4],fi[N * 4],se[N * 4]; void change(int i) { swap(v[i].arr[0][0],v[i].arr[1][0]); swap(v[i].arr[0][1],v[i].arr[1][1]); swap(v[i].arr[0][2],v[i].arr[1][2]); swap(v[i].arr[0][0],v[i].arr[0][1]); swap(v[i].arr[1][0],v[i].arr[1][1]); swap(v[i].arr[2][0],v[i].arr[2][1]); } void push_down(int i,int ll,int rr) { if(!lazy[i]) return; lazy[ls] ^= 1; lazy[rs] ^= 1; change(ls);change(rs); lazy[i] ^= 1; } inline void push_up(int i,int ll,int rr) { v[i] = mul(v[ls],v[rs]); } void build(int i,int ll,int rr) { lazy[i] = 0; if(ll == rr) { if(s[ll] == ‘1‘) v[i] = E,fi[i] = 1,se[i] = 0; else v[i] = F,fi[i] = 0,se[i] = 1; return ; } build(ls,ll,mid); build(rs,mid+1,rr); push_up(i,ll,rr); } inline void update(int i,int ll,int rr,int x,int y) { push_down(i,ll,rr); if(ll == x && rr == y) { lazy[i] ^= 1; change(i); return ; } if(y <= mid) update(ls,ll,mid,x,y); else if(x > mid) update(rs,mid+1,rr,x,y); else update(ls,ll,mid,x,mid),update(rs,mid+1,rr,mid+1,y); push_up(i,ll,rr); } inline Matix ask(int i,int ll,int rr,int x,int y) { push_down(i,ll,rr); if(ll == x && rr == y) { return v[i]; } if(y <= mid) return ask(ls,ll,mid,x,y); else if(x > mid) return ask(rs,mid+1,rr,x,y); else return mul(ask(ls,ll,mid,x,mid),ask(rs,mid+1,rr,mid+1,y)); push_up(i,ll,rr); } int main() { EE.arr[0][0] = 1,EE.arr[1][1] = 1,EE.arr[2][2] = 1; E.arr[0][0] = 1;E.arr[0][1] = 1;E.arr[0][2] = 1; E.arr[1][1] = 1;E.arr[2][2] = 1; F.arr[0][0] = 1;F.arr[1][0] = 1;F.arr[1][1] = 1; F.arr[1][2] = 1;F.arr[2][2] = 1; again.arr[0][2] = 1; int T; T = read(); while(T--) { int n,Q; n = read(); Q = read(); scanf("%s",s+1); build(1,1,n); while(Q--) { int op,l,r; op = read(); l = read(); r = read(); if(op == 1) update(1,1,n,l,r); else { now = mul(again,ask(1,1,n,l,r)); printf("%lld\n",(now.arr[0][0]+now.arr[0][1])%mod); } } } return 0; }
先考虑怎么算 s?1??,s?2??,…,s?n??
的答案。设 dp(i,0/1)
表示考虑到 s?i??
,以 0/1
结尾的串的数量。那么 dp(i,0)=dp(i−1,0)+dp(i−1,1)+1
. 1
也同理。
那么假设在某个区间之前,dp(i,0/1)=(x,y)
的话,过了这段区间,就会变成 (ax+by+c,dx+ey+f)
的形式,只要用线段树维护这个线性变化就好了。
HDU 6155 Subsequence Count 线段树维护矩阵
标签:mem size ora inline lines with define problem inf
原文地址:http://www.cnblogs.com/zxhl/p/7405538.html