[Codeforces266E]More Queries to Array...——线段树
题目链接:
题目大意:给出一个序列$a$,要求完成$Q$次操作,操作分为两种:1、$l,r,x$,将$[l,r]$的数都变为$x$。2、$l,r,k$,求$\sum\limits_{i=l}^{r}a_{i}(i-l+1)^k$,其中$k\le 5$。
因为$k$比较小,对于序列的每个位置,维护出$a_{i}*i^{k}$的值,并用线段树维护区间和。因为存在区间赋值操作,我们再维护$f[i][j]$表示$\sum\limits_{x=1}^{i}x^j$(即$j$次幂的前缀和),用两个前缀和相减即可得到区间对应需要乘的数。对于询问,我们先求出区间中维护的各次幂的和,例如当$k=2$时,$ans=\sum a_{i}*i^2-2*(l-1)\sum a_{i}*i+(l-1)^2\sum a_{i}$,暴力将各次幂的和乘上对应常数相加即为答案。其他的$k$的情况同理,根据二项式展开推一下即可。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define mod 1000000007
using namespace std;
ll s[100010][6];
ll sum[400010][6];
ll num[400010];
ll ans[6];
int n,m;
int x,k;
char ch[3];
int l,r;
ll calc(int l,int r,int k)
{
return ((s[r][k]-s[l-1][k])%mod+mod)%mod;
}
void pushup(int rt)
{
for(int i=0;i<=5;i++)
{
sum[rt][i]=sum[rt<<1][i]+sum[rt<<1|1][i];
}
}
void pushdown(int rt,int l,int r)
{
if(num[rt]!=-1)
{
int mid=(l+r)>>1;
num[rt<<1]=num[rt];
num[rt<<1|1]=num[rt];
for(int i=0;i<=5;i++)
{
sum[rt<<1][i]=num[rt]*calc(l,mid,i)%mod;
sum[rt<<1|1][i]=num[rt]*calc(mid+1,r,i)%mod;
}
num[rt]=-1;
}
}
void build(int rt,int l,int r)
{
num[rt]=-1;
if(l==r)
{
scanf("%d",&x);
for(int i=0;i<=5;i++)
{
sum[rt][i]=1ll*x*calc(l,l,i)%mod;
}
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int L,int R,int k)
{
if(L<=l&&r<=R)
{
num[rt]=1ll*k;
for(int i=0;i<=5;i++)
{
sum[rt][i]=1ll*k*calc(l,r,i)%mod;
}
return ;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(L<=mid)
{
change(rt<<1,l,mid,L,R,k);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R,k);
}
pushup(rt);
}
void query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
for(int i=0;i<=5;i++)
{
ans[i]+=sum[rt][i];
ans[i]%=mod;
}
return ;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(L<=mid)
{
query(rt<<1,l,mid,L,R);
}
if(R>mid)
{
query(rt<<1|1,mid+1,r,L,R);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
s[i][0]=1ll;
for(int j=1;j<=5;j++)
{
s[i][j]=s[i][j-1]*i%mod;
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<=5;j++)
{
s[i][j]+=s[i-1][j];
s[i][j]%=mod;
}
}
build(1,1,n);
while(m--)
{
scanf("%s%d%d%d",ch,&l,&r,&k);
if(ch[0]=='=')
{
change(1,1,n,l,r,k);
}
else
{
memset(ans,0,sizeof(ans));
query(1,1,n,l,r);
ll res=0;
if(k==0)
{
res+=ans[0],res%=mod;
}
else if(k==1)
{
res+=ans[1],res%=mod;
res-=1ll*(l-1)*ans[0]%mod,res%=mod;
}
else if(k==2)
{
res+=ans[2],res%=mod;
res-=2ll*(l-1)*ans[1]%mod,res%=mod;
res+=1ll*(l-1)*(l-1)%mod*ans[0]%mod,res%=mod;
}
else if(k==3)
{
res+=ans[3],res%=mod;
res-=3ll*(l-1)*ans[2]%mod,res%=mod;
res+=3ll*(l-1)*(l-1)%mod*ans[1]%mod,res%=mod;
res-=1ll*(l-1)*(l-1)%mod*(l-1)%mod*ans[0]%mod,res%=mod;
}
else if(k==4)
{
res+=ans[4],res%=mod;
res-=4ll*(l-1)*ans[3]%mod,res%=mod;
res+=6ll*(l-1)*(l-1)%mod*ans[2]%mod,res%=mod;
res-=4ll*(l-1)*(l-1)%mod*(l-1)%mod*ans[1]%mod,res%=mod;
res+=1ll*(l-1)*(l-1)%mod*(l-1)%mod*(l-1)%mod*ans[0]%mod,res%=mod;
}
else
{
res+=ans[5],res%=mod;
res-=5ll*(l-1)*ans[4]%mod,res%=mod;
res+=10ll*(l-1)*(l-1)%mod*ans[3]%mod,res%=mod;
res-=10ll*(l-1)*(l-1)%mod*(l-1)%mod*ans[2]%mod,res%=mod;
res+=5ll*(l-1)*(l-1)%mod*(l-1)%mod*(l-1)%mod*ans[1]%mod,res%=mod;
res-=1ll*(l-1)*(l-1)%mod*(l-1)%mod*(l-1)%mod*(l-1)%mod*ans[0]%mod,res%=mod;
}
res=(res%mod+mod)%mod;
printf("%lld\n",res);
}
}
}
[Codeforces266E]More Queries to Array...——线段树的更多相关文章
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- Codeforces 1114F Please, another Queries on Array? 线段树
Please, another Queries on Array? 利用欧拉函数的计算方法, 用线段树搞一搞就好啦. #include<bits/stdc++.h> #define LL ...
- 暑假集训单切赛第一场 CF 266E More Queries to Array(线段树+二项式展开式)
比赛时,第二题就是做的这个,当时果断没仔细考虑,直接用线段树暴力求.结果易想而知,超时了. 比赛后搜了搜题解,恍然大悟. 思路:显然用线段树,但是由于每次查询都会有变,所以不可能存储题目中的式子. ...
- Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]
Codeforces 洛谷:咕咕咕 CF少有的大数据结构题. 思路 考虑一些欧拉函数的性质: \[ \varphi(p)=p-1\\ \varphi(p^k)=p^{k-1}\times (p-1)= ...
- Can you answer these queries? HDU 4027 线段树
Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- codeforces 719E E. Sasha and Array(线段树)
题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...
- CodeChef DISTNUM2 Easy Queries 节点数组线段树
Description You are given an array A consisting of N positive integers. You have to answer Q queries ...
- spoj gss2 : Can you answer these queries II 离线&&线段树
1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...
随机推荐
- Java多线程编程核心技术(一)Java多线程技能
1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...
- java OOM还在看log日志,兄弟你错的的很严重,正确方式是分析dump文件
目录 OOM异常--intsmaze 正确姿势dump文件分析--intsmaze 正确的姿势--intsmaze dump丢失打印--intsmaze 哪些内存溢出会产生dump文件--intsma ...
- 旋转数组的最小数字 - 剑指offer 面试题8
题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...
- H5 32-百度首页
32-百度首页 新 闻 网 页 贴 吧 知 道 音 乐 图 片 视 频 地 图 百科 文库 hao123 | 更多>> 百度地图带你吃喝玩乐,全心全意为人民服务 把百度设为主页 安装百度卫 ...
- H5 文本属性
06-文本属性 我是文字 我是文字 我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是段落我是 ...
- iOS开发 横向分页样式 可左右滑动或点击头部栏按钮进行页面切换
iOS开发 横向分页样式 可左右滑动或点击头部栏按钮进行页面切换 不多说直接上效果图和代码 1.设置RootViewController为一个导航试图控制器 // Copyright © 2016年 ...
- p86商空间也是Banach空间
1.为什么要引入Zk? 2.为什么这个等式成立,和为什么要引入uk? 3.为什么为什么等于0? 属于M,则商空间是0元,p128最上面的第二个笔记
- MyBatis模糊查询不报错但查不出数据的一种解决方案
今天在用MyBatis写一个模糊查询的时候,程序没有报错,但查不出来数据,随即做了一个测试,部分代码如下: @Test public void findByNameTest() throws IOEx ...
- Zk搭建(Zookeeper)
第一步: 上传----解压 tar -zxvf zookeeper-3.4.5.tar.gz---- 配置zk的环境变量 ----------配置源码 vim ...
- MySQL 主从同步遇到的问题及解决方案
在做某个项目的时候,使用主从数据库,master负责update.delete.insert操作,而slave负责select操作. 情景1:发表文章与查看文章 可以认为这个项目是一个博客系统,这里就 ...