codeforces 266E More Queries to Array 線段樹

來源:互聯網
上載者:User

題目大意:給你一串數列,a[1]~a[n]。有兩種操作

操作1:", (1 ≤ l ≤ r ≤ n; 0 ≤ x ≤ 109).
表示將區間[l,r]中的數全賦值為x。

操作2:"", (1 ≤ l ≤ r ≤ n; 0 ≤ k ≤ 5).
表示計算的值,模數1000000007後輸出。

先給你q個操作,對於每一個操作2,輸出對應的值。

 

思路:這道題的關鍵就在k的範圍很小,只有0到5,所以可以考慮建6可線段樹分別討論。對於特定的k,怎麼求要求計算的值呢?在做過幾次嘗試後,我發現很難直接求得(對於不同的 l r,所乘的係數也不同)。既然直接求難度大,那我們不妨分開來求,將所要求的式子拆開來看看。

對於k=0,則相當於求區間和。

對於k=1,原式可化為 a[i]+(1-l);

對於k=2,原式可化為 a[i]^2-2*(l-1)*a[i]+(l-1)^2;

對於k=3,原式可化為 a[i]^3-3*(l-1)*a[i]^2+3*(l-1)^2*a[i]-(l-1)^3;

。。。。。。

我們可以發現對於每個a[i]項,它所乘的係數變得可以確定了(每一個都和(l-1)有關,滿足二項式定理)。如果我們線上段樹中,對於每一個個區間我們維護,那麼對於每一個不同的K(k很小),我們都可以根據上面的式子,展開來分別求,事情到了這一步演算法已經基本成型了,剩下的就是實現了。我們首先要建立6個線段樹來維護,因為資料量大,所以我們首先將(i^j)%1000000007的值預先處理一下,用到的時候在調用即可。對於操作1,我們如果把一個區間的數全賦值為x,則該區間的和則為x*(l^j+(l+1)^j+....(r)^j),對於括弧裡的值也可以通過預先處理來實現,最後注意由於所求的值相當的大,在一些中間運算中可能會爆
long long的,所以一定要在每一個可能越界的地方模數。最後看實現。

#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#define maxn 100010#define mod 1000000007using namespace std;#define mid ((t[p].l+t[p].r)>>1)#define ls (p<<1)#define rs (ls|1)long long pow[maxn][6],num[maxn][6];long long a[maxn];void init(){    long long i;    memset(num,0,sizeof(num));    memset(pow,0,sizeof(pow));    for(i=0;i<=100000;i++)    {        int j;        for(j=0;j<6;j++)        {            int k=j;            long long tmp=1;            while(k--)            tmp=(tmp*i)%mod;            pow[i][j]=tmp;            if(i!=0)            num[i][j]=(num[i-1][j]+tmp)%mod;        }    }}struct tree{    int l,r;    int lazy;    long long sum[6];}t[maxn<<2];void pushup(int p){ int i; for(i=0;i<6;i++) t[p].sum[i]=(t[ls].sum[i]+t[rs].sum[i])%mod;}void update(int p,int val){    t[p].lazy=val;    int i,l=t[p].l,r=t[p].r;    for(i=0;i<6;i++)    t[p].sum[i]=((val*(num[r][i]-num[l-1][i]))%mod+mod)%mod;}void pushdown(int p){    if(t[p].lazy!=-1)    {        update(ls,t[p].lazy);        update(rs,t[p].lazy);        t[p].lazy=-1;    }}void build(int p,int l,int r){    t[p].l=l,t[p].r=r,t[p].lazy=-1;    if(l==r)    {        int i;        for(i=0;i<6;i++)        {            t[p].sum[i]=(pow[l][i]*a[l])%mod;        }        return;    }    build(ls,l,mid);    build(rs,mid+1,r);     pushup(p);}void add(int p,int l,int r,int val){    if(t[p].l==l&&t[p].r==r)    {        update(p,val);        return;    }    pushdown(p);    if(l>mid)    add(rs,l,r,val);    else if(r<=mid)    add(ls,l,r,val);    else    {        add(ls,l,mid,val);        add(rs,mid+1,r,val);    }    pushup(p);}long long query(int p,int l,int r,int k){    if(t[p].l==l&&t[p].r==r)    {        return t[p].sum[k];    }    pushdown(p);    if(l>mid)    return query(rs,l,r,k);    else if(r<=mid)    return query(ls,l,r,k);    else    {        return (query(ls,l,mid,k)+query(rs,mid+1,r,k))%mod;    }}int l,r;long long g(int a,int b,int c){    return (query(1,l,r,c)*((a*pow[l-1][b])%mod))%mod;}int main(){    init();    int n,q,i;    scanf("%d%d",&n,&q);    for(i=1;i<=n;i++)    scanf("%I64d",&a[i]);    build(1,1,n);    char str[2];    int x;    while(q--)    {        scanf("%s%d%d%d",str,&l,&r,&x);        if(str[0]=='=')        {            add(1,l,r,x);        }        else        {            long long tmp=0;            if(x==0)            {                tmp=query(1,l,r,0);            }            else if(x==1)            {                tmp=((g(1,0,1)-g(1,1,0))%mod+mod)%mod;            }            else if(x==2)            {               tmp=((g(1,0,2)-g(2,1,1)+g(1,2,0))%mod+mod)%mod;            }             else if(x==3)            {                tmp=((g(1,0,3)-g(3,1,2)+g(3,2,1)-g(1,3,0))%mod+mod)%mod;            }            else if(x==4)            {                tmp=((g(1,0,4)-g(4,1,3)+g(6,2,2)-g(4,3,1)+g(1,4,0))%mod+mod)%mod;            }            else if(x==5)            {                tmp=((g(1,0,5)-g(5,1,4)+g(10,2,3)-g(10,3,2)+g(5,4,1)-g(1,5,0))%mod+mod)%mod;            }            printf("%I64d\n",tmp);        }    }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.