#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
typedef long long ll;
typedef pair< int , int > pii;
typedef unsigned long long ull;
#ifndef ONLINE_JUDGE
void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);}
void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R>
void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1;
while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T>
void print( const T t){cout<<t<<endl;} template < typename F, typename ...R>
void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T>
void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;}
#endif
template < typename T> bool umax(T&a, const T&b){ return b<=a? false :(a=b, true );}
template < typename T> bool umin(T&a, const T&b){ return b>=a? false :(a=b, true );}
template < typename T>
void V2A(T a[], const vector<T>&b){ for ( int i=0;i<b.size();i++)a[i]=b[i];}
template < typename T>
void A2V(vector<T>&a, const T b[]){ for ( int i=0;i<a.size();i++)a[i]=b[i];}
const double PI = acos (-1.0);
const int INF = 1e9 + 7;
/* -------------------------------------------------------------------------------- */
template < int mod>
struct ModInt {
const static int MD = mod;
int x;
ModInt(ll x = 0): x(x % MD) {}
int get() { return x; }
ModInt operator + ( const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD? x0 : x0 - MD); }
ModInt operator - ( const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD? x0 + MD : x0); }
ModInt operator * ( const ModInt &that) const { return ModInt(( long long )x * that.x % MD); }
ModInt operator / ( const ModInt &that) const { return * this * that.inverse(); }
ModInt operator += ( const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
ModInt operator -= ( const ModInt &that) { x -= that.x; if (x < 0) x += MD; }
ModInt operator *= ( const ModInt &that) { x = ( long long )x * that.x % MD; }
ModInt operator /= ( const ModInt &that) { * this = * this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b; std::swap(a, b);
u -= t * v; std::swap(u, v);
}
if (u < 0) u += MD;
return u;
}
};
typedef ModInt<1000000007> mint;
const int maxn = 1e5 + 7;
const int md = 1e9 + 7;
int a[maxn];
class SegTree {
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
struct Node {
mint var1, var2, con1, con2;
};
Node tree[maxn << 2];
int n;
Node &merge( const Node &ul, const ll &Llen, const Node &ur, const ll &Rlen) {
static Node ans;
if (Llen & 1) {
ans.var1 = ul.var1 + ur.var2 + ul.con1 * Rlen;
ans.var2 = ul.var2 + ur.var1 + ul.con2 * Rlen;
ans.con1 = ul.con1 + ur.con2;
ans.con2 = ul.con2 + ur.con1;
}
else {
ans.var1 = ul.var1 + ur.var1 + ul.con1 * Rlen;
ans.var2 = ul.var2 + ur.var2 + ul.con2 * Rlen;
ans.con1 = ul.con1 + ur.con1;
ans.con2 = ul.con2 + ur.con2;
}
return ans;
}
void build( int l, int r, int rt) {
if (l == r) {
Node &u = tree[rt];
u.var1 = u.con1 = a[l];
u.var2 = u.con2 = 0;
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
int len = r - l + 1;
tree[rt] = merge(tree[rt << 1], m - l + 1, tree[rt << 1 | 1], r - m);
}
void update( int p, int x, int l, int r, int rt) {
if (l == r) {
Node &u = tree[rt];
u.var1 = u.con1 = x;
u.var2 = u.con2 = 0;
return ;
}
int m = (l + r) >> 1;
if (p <= m) update(p, x, lson);
else update(p, x, rson);
tree[rt] = merge(tree[rt << 1], m - l + 1, tree[rt << 1 | 1], r - m);
}
Node query( int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) return tree[rt];
int m = (l + r) >> 1;
if (R <= m) return query(L, R, lson);
if (L > m) return query(L, R, rson);
Node ul = query(L, m, lson), ur = query(m + 1, R, rson);
return merge(ul, m - L + 1, ur, R - m);
}
Node get(ll cnt) {
if (cnt == 1) return tree[1];
Node u = get(cnt >> 1);
ll c = cnt >> 1;
u = merge(u, c * n, u, c * n);
if (cnt & 1) u = merge(u, c * n * 2, tree[1], n);
return u;
}
public :
void build( int n) { this ->n = n; build(1, n, 1); }
void update( int p, int x) { update(p, x, 1, n, 1); }
mint query(ll L, ll R) {
ll lid = (L - 1) / n + 1, rid = (R - 1) / n + 1, dif = rid - lid;
L = (L - 1) % n + 1;
R = (R - 1) % n + 1;
if (dif == 0) return query(L, R, 1, n, 1).var1;
Node ul = query(L, n, 1, n, 1), ur = query(1, R, 1, n, 1);
int Llen = n - L + 1, Rlen = R;
mint var = ul.var1 + ul.con1 * ((dif - 1) * n + Rlen);
if (dif - 1) {
Node buf = get(dif - 1);
if (Llen & 1) var += buf.var2 + buf.con2 * Rlen;
else var += buf.var1 + buf.con1 * Rlen;
}
if ((Llen + (dif - 1) * n) & 1) var += ur.var2;
else var += ur.var1;
return var;
}
};
SegTree st;
char s[maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen ( "in.txt" , "r" , stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int T, n, m, t;
ll x, y;
cin >> T;
while (T --) {
scanf ( "%*c%s" , s);
int n = strlen (s);
for ( int i = 0; i < n; i ++) {
a[i + 1] = s[i] - ‘0‘ ;
}
st.build(n);
cin >> m;
while (m --) {
scanf ( "%d%lld%lld" , &t, &x, &y);
if (t == 1) st.update(x, y);
else printf ( "%d\n" , st.query(x, y).get());
}
}
return 0;
}
|