Codeforces Round #2 (Div. 2) C. Candies! (ST table)

Keywords: less

General meaning

Given a sequence of powers with length of 2, where a I < 10, the adjacent two numbers are merged into (a[i]+a[i+1])%10 at a time. If a [i]+a [i+1]>= 10, value plus 1. This will halve the length of the sequence. Now let's ask M what the total value is when the [L, R] interval is merged into a single number. R - L +1 is also the power of 2.

thinking

At first, I want to build a line segment tree in 1-n, and a line segment tree in 2-n, and then query it in odd and even parts of the left endpoint. However, there is a problem that the query interval may be covered by nodes of multiple segment trees, so that it is not actually merged into a single number. Only when the precise interval is covered by the nodes of a segment tree can it be correct.

So this problem only needs to write a ST table. tab[x][y] maintains the value of the combination of intervals with X as the left endpoint and length (1 y), while val[x][y] maintains the value. Because the interval of inquiry is exactly the power of 2, it is only necessary to find the corresponding value of the left endpoint.

Code

Stick the ST table board, I feel I use less, not very skilled.

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define maxm 500006
#define ll long long int
#define INF 0x3f3f3f3f
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
#define mem(a) memset(a,0,sizeof(a))
#define sqr(x) (x*x)
#define inf (ll)2e18+1
#define mod 1000000007
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
     return f*x;
}
int n,m,a[maxn];
int tab[20][maxn],val[20][maxn],mm[maxn];
void initRMQ(int n,int b[]){
    mm[0]=-1;
    inc(i,1,n){
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        tab[0][i]=b[i];
    }
    inc(j,1,mm[n])for(int i=1;i+(1<<j)-1<=n;i++){
        tab[j][i]=(tab[j-1][i]+tab[j-1][i+(1<<(j-1))])%10;
        val[j][i]=val[j-1][i]+val[j-1][i+(1<<(j-1))]+(tab[j-1][i]+tab[j-1][i+(1<<(j-1))]>=10);
    }
}
int main()
{
    n=read();
    inc(i,1,n)a[i]=read();
    initRMQ(n,a);
    m=read();
    int x,y;
    inc(i,1,m){
        x=read();y=read();
        printf("%d\n",val[mm[y-x+1]][x]);
    }
    return 0;
}

Posted by ledtear on Sun, 06 Oct 2019 08:28:20 -0700