列表

详情


NC221766. PiggyCalculator

描述

Piggy is developing a fantastic calculator. This calculator innovatively invents a binary operator symbol that perfectly mixes addition and multiplication, which we call   (k is a positive integer).

The value of  is equal to . The precedence between operators is that the higher the k, the higher the priority. The higher priority goes first. For example,has a higher priority than , so you must calculate  before . The operators are left-associative. Between the operators with the same priority, you should calculate them from left to right. For example, in the expression , you must calculate firstly.

Now, Piggy wants to ask you to help him implement a function. There is an expression with n numbers and n-1 operators. At the same time, there are q queries, each of them shaped as (L,R). You need to calculate the result of the sub-expression formed by the L-th number to the R-th number.

输入描述

The first line contains one positive integer n  -- the length of the expression.

The second line contains n positive integers   -- the n numbers from left to right in the expression.

The third line contains n-1 positive integers  , where the i-th operator from left to right is  and is  between the i-th number and the -th number.

The forth line contains one positive integer q  -- the number of queris.

The next q lines describe the queries, where the i-th line contains two integers L_i, R_i .

输出描述

For each query, print an integer in one line -- the result of the calculation. Since the answer may be very large, you only need to print the answer modulo .

示例1

输入:

5
1 2 3 4 5
5 2 3 4
2
1 5
2 4

输出:

264
46

说明:

In the first query, the equation is 1 \odot^5 2 \odot^2 3 \odot^3 4 \odot^4 5 = 15 \odot^2 3 \odot^3 4 \odot^4 5 = 15 \odot^2 3 \odot^3 36 = 15 \odot^2 117 = 264.

In the second query, the equation is 2 \odot^2 3 \odot^3 4 = 2 \odot^2 21 = 46.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 1332ms, 内存消耗: 194864K, 提交时间: 2021-05-12 19:42:19

#include  <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=3e5+5,N=20,mod=1e9+7;
int n,a[M],k[M],rt,son[M][2],fa[M][N],dep[M],val[M],prefa[M][N][2],prek[M][N][2],preval[M][N][2];
vector<int> st;
void dfs1(int x)
{
    for(int i=0;i<2;i++)
        if(int y=son[x][i])
        {
            fa[y][0]=x;
            for(int j=1;j<N;j++)fa[y][j]=fa[fa[y][j-1]][j-1];
            dep[y]=dep[x]+1;
            dfs1(y);
            val[x]=(val[x]+val[y])%mod;
        }
        else val[x]=(val[x]+a[x+i])%mod;
    val[x]=(ll)val[x]*k[x]%mod;
}
int getval(int x,int g){return son[x][g]?val[son[x][g]]:a[x+g];}
void dfs2(int x)
{
    for(int i=0;i<2;i++)
        if(int y=son[x][i])
        {
            prefa[y][0][0]=i?prefa[x][0][0]:x;prefa[y][0][1]=i?x:prefa[x][0][1];
            prek[y][0][0]=prek[y][0][1]=k[y];
            preval[y][0][0]=(ll)getval(y,1)*k[y]%mod;preval[y][0][1]=(ll)getval(y,0)*k[y]%mod;
            for(int j=1;j<N;j++)for(int c=0;c<2;c++)
            {
                prefa[y][j][c]=prefa[prefa[y][j-1][c]][j-1][c];
                prek[y][j][c]=(ll)prek[y][j-1][c]*prek[prefa[y][j-1][c]][j-1][c]%mod;
                preval[y][j][c]=((ll)preval[y][j-1][c]*prek[prefa[y][j-1][c]][j-1][c]%mod+preval[prefa[y][j-1][c]][j-1][c])%mod;
            }
            dfs2(y);
        }
}
int lca(int x,int y)
{
    if(dep[y]>dep[x])swap(x,y);
    for(int i=N-1;i>=0;i--)
        if(dep[fa[x][i]]>=dep[y])
            x=fa[x][i];
    if(x==y)return x;
    for(int i=N-1;i>=0;i--)
        if(fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
int que(int x,int d,int g)
{
    int ans=a[x+g];
    for(int i=N-1;i>=0;i--)
    {
        int t=prefa[x][i][g];
        if(t&&dep[t]>=dep[d])
            ans=((ll)ans*prek[x][i][g]%mod+preval[x][i][g])%mod,x=t;
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d",&k[i]);
        while(!st.empty()&&k[st.back()]>=k[i])
        {
            son[i][0]=st.back();
            st.pop_back();
        }
        if(!st.empty())son[st.back()][1]=i;
        else rt=i;
        st.push_back(i);
    }
    dep[rt]=1;
    dfs1(rt);
    dfs2(rt);
    int q;scanf("%d",&q);
    while(q--)
    {
        int l,r;scanf("%d%d",&l,&r);
        if(l==r)printf("%d\n",a[l]);
        else
        {
            int d=lca(l,r-1);
            int ans=(ll)k[d]*(que(l,d,0)+que(r-1,d,1))%mod;
            printf("%d\n",ans);
        }
    }
	return 0;
}

上一题