CodeForces 266E More Queries to Array... 线段树

来源:互联网 发布:c语言库函数大全 编辑:程序博客网 时间:2024/06/03 16:39

题意:两种操作:

1 区间【l,r】变为一个值

2 查询   ,k<=5

解题:线段树每个点记录a[l]*l^k,统计区间和,直接查询即可。然后把要查询的值多项式展开转化一下,当k=5时,就要同时查询k=0,1,2,3,4,5的值。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string.h>#include<algorithm>using namespace std;#define mod 1000000007#define ls rt<<1#define rs rt<<1|1#define ll __int64using namespace std;const int maxn=200010;struct T{    int l,r;    ll flag;    ll sum[6];}T[maxn<<2];int a[maxn];ll s2[maxn][6];ll s1[maxn][6]= {0};ll C[6][6];ll s3[maxn][6];void init(){    int maxx=100010;    for(int i=0; i<6; i++)    {        C[i][0]=C[i][i]=1;        for(int j=1; j<i; j++)            C[i][j]=(C[i-1][j]+C[i-1][j-1]);    }    for(int i=1; i<=maxx; i++)    {        s2[i][0]=1;        s1[i][0]=i;        s3[i][0]=1;    }    for(int i=1; i<6; i++)    {        for(int j=1; j<=maxx; j++)        {            s2[j][i]=(s2[j][i-1]*j)%mod;            s1[j][i]=(s1[j-1][i]+s2[j][i])%mod;            s3[j][i]=((s3[j][i-1]*(1-j))%mod+mod)%mod;        }    }}void push_up(int rt){//    //0//    T[rt].sum[0]=T[ls].sum[0]+T[rs].sum[0];//    int len=T[ls].r-T[ls].l+1;//    //1//    T[rt].sum[1]=T[ls].sum[1]+T[rs].sum[1]+len*T[rs].sum[0];//    //2//    T[rt].sum[2]=T[ls].sum[2]+T[rs].sum[2]+len*len*T[rs].sum[0]+2*len*T[rs].sum[1];//    //3//    T[rt].sum[3]=T[ls].sum[3]+T[rs].sum[3]+len*len*len*T[rs].sum[0]+3*len*len*T[rs].sum[1]+3*len*T[rs].sum[2];//    //4//    T[rt].sum[4]=T[ls].sum[4]+T[rs].sum[4]+len*len*len*len*T[rs].sum[0]+6*len*len*T[rs].sum[2]+4*len*T[rs].sum[3]+4*len*len*len*T[rs].sum[1];//    //5//    T[rt].sum[5]=T[ls].sum[5]+T[rs].sum[5]+len*len*len*len*len*T[rs].sum[0]+5*len*len*len*len*T[rs].sum[1]+10*len*len*len*T[rs].sum[2]+10*len*len*T[rs].sum[3]+5*len*T[rs].sum[4];    for(int i=0; i<6; i++)        T[rt].sum[i]=(T[ls].sum[i]+T[rs].sum[i])%mod;}//void change(int rt,int val)//{//    int l=T[rt].l;//    int r=T[rt].r;//    for(int i=0;i<=5;i++)//    {//    ll tmp=((s1[r][i]-s1[l-1][i])%mod+mod)%mod;//    T[rt].sum[i]=((ll)tmp*val)%mod;//    }//}void update(int rt,int left,int right,int x);void push_down(int rt){    if(T[rt].flag!=-1)    {        int l=T[rt].l,r=T[rt].r,mid=(l+r)>>1;        update(ls,l,mid,T[rt].flag);        update(rs,mid+1,r,T[rt].flag);        T[rt].flag=-1;    }}void bulid(int rt,int left,int right){    T[rt].l=left;    T[rt].r=right;    T[rt].flag=-1;    if(left==right)    {        for(int i=0; i<6; i++)            T[rt].sum[i]=(a[left]*s2[left][i])%mod;        return ;    }    int mid=(left+right)>>1;    bulid(ls,left,mid);    bulid(rs,mid+1,right);    push_up(rt);}void update(int rt,int left,int right,int val){    if(T[rt].l==left&&T[rt].r==right)    {        T[rt].flag=val;        int l=T[rt].l;        int r=T[rt].r;        for(int i=0; i<6; i++)        {            ll tmp=((s1[r][i]-s1[l-1][i])%mod+mod)%mod;            T[rt].sum[i]=(tmp*val)%mod;        }        return ;    }    push_down(rt);    int mid=(T[rt].l+T[rt].r)>>1;    if(right<=mid) update(ls,left,right,val);    else if(left>mid) update(rs,left,right,val);    else    {        update(ls,left,mid,val);        update(rs,mid+1,right,val);    }    push_up(rt);}ll query(int rt,int left,int right,int k){    if(T[rt].l==left&&T[rt].r==right)        return T[rt].sum[k];    int mid=(T[rt].l+T[rt].r)>>1;    push_down(rt);    if(right<=mid) return query(ls,left,right,k);    else if(left>mid) return query(rs,left,right,k);    return (query(ls,left,mid,k)+query(rs,mid+1,right,k))%mod;}char op[10];int _a,b,c;int main(){    int n,m;//    freopen("in.txt","r",stdin);    init();    while(scanf("%d%d",&n,&m)!=EOF)    {    for(int i=1; i<=n; i++)        scanf("%d",&a[i]);    bulid(1,1,n);    for(int i=1;i<=m;i++)    {        scanf("%s",&op);        scanf("%d%d%d",&_a,&b,&c);        if(op[0]=='=') update(1,_a,b,c);        else        {            ll ans=0;            for(int i=0; i<=c; i++)                ans=((((query(1,_a,b,i)*C[c][i])%mod*s3[_a][c-i])%mod+ans)%mod+mod)%mod;            printf("%I64d\n",ans);        }    }    }    return 0;}


0 0
原创粉丝点击