HDU 6562 lovers 2018CCPC Jilin H (segment tree)

Meaning of the questions:

Initially empty string n, m operations:

1 to [l, r] craniocaudal plus a string of all 'd', the original string x becomes dxd

2. seeking [l, r] string represents all the figures and mod 1e9 + 7

Ideas:

It is said to be hard-core segment tree. .

For the tree line we have to first find out the time change for a range of changes to the range to be asked (sum) caused

For a number x, if he operated once (a craniocaudal plus c), it will become $ 10x + c + c ^ {n_i + 1} $, $ where $ n_i x denotes the actual length (number of bits )

So for the current interval operation, the current interval sum becomes $ 10sum + (r-l + 1) * c + c * sumlen $, where $ sumlen = \ sum_ {i = l} ^ {r} 10 ^ {n_i +1} $

This thing should be written in place of the fight laziness mark

The formula has obviously had an operation sequence, we only need to operate Series $ d_3d_2d_1xd_1d_2d_3 $ into $ d_3d_2d_1 $ and $ d_1d_2d_3 $ (save with two numbers), save two marks addl lazy and addr respectively

But pushdown time to pay attention, lazy marker is present in the last node has operated the inside, so pay attention to the order of the objects and operations

In the pushdown, if only spread to a next node (such as a LC),

那么$sum[lc]=addr[root]+sum[lc]*addlen[root]+addl[root]*addlen[root]*10^{n_i+1}/10$

Therefore, the entire lc interval, $ sum [lc] = \ sum addr [root] + sum [lc] * addlen [root] + addl [root] + addl [root] * addlen [root] * sumlen [root] / 10 $

Everything else is a routine operation, take note of the time do not overflow

Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);


ll fp(ll a, ll n){
    ll ans = 1;
    while(n){
        if(n & 1) ans *= a;
        a *= a;
        a %= mod;
        n >>= 1;
        ans %= mod;
    }
    return ans;
}
ll div10;
ll sum[maxn];
ll sumlen[maxn];
ll addl[maxn],addr[maxn],addlen[maxn];
int t;
int n, m;
void build(int l, int r, int root){
    int mid = (l+r)>>1;
    addl[root]=addr[root]=0;
    addlen[root]=1;
    if(l==r){
        sum[root] = 0;
        sumlen[root] = 10;
        return;
    }
    build(lson);
    build(rson);
    sum[root]=0;
    sumlen[root]=sumlen[lc]+sumlen[rc];
    sumlen[root]%=mod;
    return;
}
void pushdown(int l, int r, int root){
    int mid = (l+r)>>1;
    if(addlen[root]>1){
        addl[lc]=(addl[root]*addlen[lc]%mod+addl[lc])%mod;
        addl[rc]=(addl[root]*addlen[rc]%mod+addl[rc])%mod;
        addr[lc]=(addr[lc]*addlen[root]%mod+addr[root])%mod;
        addr[rc]=(addr[rc]*addlen[root]%mod+addr[root])%mod;
        addlen[lc]=addlen[lc]*addlen[root]%mod;
        addlen[rc]=addlen[rc]*addlen[root]%mod;

        sum[lc]=(addr[root]*(mid-l+1)%mod+sum[lc]*addlen[root]%mod+addl[root]*addlen[root]%mod*sumlen[lc]%mod*div10%mod)%mod;
        sum[rc]=(addr[root]*(r-mid)%mod+sum[rc]*addlen[root]%mod+addl[root]*addlen[root]%mod*sumlen[rc]%mod*div10%mod)%mod;

        sumlen[lc]=(sumlen[lc]*addlen[root]%mod*addlen[root]%mod)%mod;
        sumlen[rc]=(sumlen[rc]*addlen[root]%mod*addlen[root]%mod)%mod;

        addl[root]=addr[root]=0;
        addlen[root]=1;
    }
}
void update(int ql, int qr, ll val, int l, int r, int root){
    int mid = (l+r)>>1;
    if(ql<=l&&r<=qr){
        sum[root]=(10*sum[root]%mod+(r-l+1)*val%mod+val*sumlen[root]%mod)%mod;
        sumlen[root]=sumlen[root]*100%mod;
        addl[root]=(addl[root]+val*addlen[root])%mod;
        addr[root]=(addr[root]*10+val)%mod;
        addlen[root]=(addlen[root]*10)%mod;
        return;
    }
    pushdown(l,r,root);
    if(ql<=mid)update(ql,qr,val,lson);
    if(qr>mid)update(ql,qr,val,rson);
    sum[root]=(sum[lc]+sum[rc])%mod;
    sumlen[root]=(sumlen[lc]+sumlen[rc])%mod;
    return;
}
ll query(int ql, int qr, int l, int r, int root){
    int mid = (l+r)>>1;
    if(ql<=l&&r<=qr)return sum[root]%mod;
    ll ans = 0;
    pushdown(l,r,root);
    if(ql<=mid)ans+=query(ql,qr,lson);
    if(qr>mid)ans+=query(ql,qr,rson);
    return ans%mod;
}
char op[5];
int main(){
    scanf("%d", &t);
    div10=fp(10,mod-2)%mod;
    for(int ncase = 1; ncase <= t; ncase++){
        scanf("%d %d", &n, &m);
        build(1,n,1);
        printf("Case %d:\n",ncase);
        while(m--){
            ll w;
            int x, y;
            scanf("%s",op+1);
            scanf("%d %d", &x, &y);
            if(op[1]=='w'){
                scanf("%lld", &w);
                update(x, y, w, 1, n, 1);
            }
            else{
                printf("%lld\n",query(x,y,1,n,1)%mod);
            }
        }

    }

    return 0;
}
/*
2
3 3
wrap 1 3 1
wrap 2 4 3
query 1 2
4 4
wrap 1 3 0
wrap 2 4 3
query 1 4
query 2 3

1
4 4
wrap 1 3 0
wrap 2 4 3

3
4 4
wrap 1 4 2
wrap 1 4 3
wrap 1 4 1
wrap 2 4 6
3 2
wrap 1 3 0
wrap 2 2 1
5 3
wrap 1 5 1
wrap 2 6 0
wrap 3 5 2
 */

 

Guess you like

Origin www.cnblogs.com/wrjlinkkkkkk/p/11203018.html