分析:

数据范围表示:c特别的小(c<20)

我们可以考虑nlogn*c^2的算法。

线段树维护区间信息:f[i]表示在[l,r]这段区间中选择i个数相乘的和。

因此,我们可以将区间看成一个点,在PushUp的时候用背包的方式更新父节点。(仔细观察发现这是卷积)

剩下的就是一些优化了...

附上代码:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
using namespace std;
#define N 50005
#define mod 19940417
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
int C[N][21],a[N],n,Q;
char s[10];
struct node
{
ll f[21],tag,add;
int siz;
node ()
{
memset(f,0,sizeof(f));
siz=tag=add=0;
}
node operator +(const node &b)
{
node c;
c.f[0]=1;
for(int i=1;i<=20;i++)
{
for(int j=0;j<=i;j++)
{
c.f[i]+=f[j]*b.f[i-j]%mod;
c.f[i]%=mod;
}
}
c.siz=siz+b.siz;
return c;
}
void plus(ll x)
{
add+=x;
add%=mod;
for(int i=min(siz,20);i;i--)
{
ll y=x;
for(int j=1;j<=i;j++)
{
f[i]=(f[i]+y*f[i-j]%mod*C[siz-i+j][j]%mod)%mod;
y=y*x%mod;
}
}
}
void rev()
{
tag^=1;
add=(mod-add)%mod;
for(int i=min(siz,20);i;i--)
{
if(i&1)f[i]=(mod-f[i])%mod;
}
}
}tr[N<<2];
void PushUp(int rt)
{
tr[rt]=tr[rt<<1]+tr[rt<<1|1];
}
void build(int l,int r,int rt)
{
if(l==r)
{
tr[rt].f[1]=a[l];
tr[rt].f[0]=tr[rt].siz=1;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void PushDown(int rt)
{
if(tr[rt].tag)
{
tr[rt<<1].rev();
tr[rt<<1|1].rev();
tr[rt].tag=0;
}
if(tr[rt].add)
{
tr[rt<<1].plus(tr[rt].add);
tr[rt<<1|1].plus(tr[rt].add);
tr[rt].add=0;
}
}
void Update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
tr[rt].plus(c);
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(m>=L)Update(L,R,c,lson);
if(m<R)Update(L,R,c,rson);
PushUp(rt);
}
void Update_rev(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
tr[rt].rev();
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(m>=L)Update_rev(L,R,lson);
if(m<R)Update_rev(L,R,rson);
PushUp(rt);
}
node query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return tr[rt];
}
PushDown(rt);
int m=(l+r)>>1;
if(m>=R)return query(L,R,lson);
if(m<L)return query(L,R,rson);
return query(L,R,lson)+query(L,R,rson);
}
int main()
{
scanf("%d%d",&n,&Q);
C[0][0]=1;
for(int i=1;i<=n;i++)
{
C[i][0]=1;
for(int j=1;j<=20;j++)
{
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,n,1);
while(Q--)
{
int x,y,z;
scanf("%s%d%d",s,&x,&y);
if(s[0]=='I')
{
scanf("%d",&z);
Update(x,y,z,1,n,1);
}else if(s[0]=='R')
{
Update_rev(x,y,1,n,1);
}else
{
scanf("%d",&z);
printf("%lld\n",(query(x,y,1,n,1).f[z]+mod)%mod);
}
}
return 0;
}

  

序列操作 BZOJ2962 线段树的更多相关文章

  1. 【BZOJ2962】序列操作(线段树)

    [BZOJ2962]序列操作(线段树) 题面 BZOJ 题解 设\(s[i]\)表示区间内选择\(i\)个数的乘积的和 考虑如何向上合并? \(s[k]=\sum_{i=0}^klson.s[i]*r ...

  2. BZOJ_1858_[Scoi2010]序列操作_线段树

    BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...

  3. 【BZOJ1858】序列操作(线段树)

    [BZOJ1858]序列操作(线段树) 题面 BZOJ 题解 这题思路很简单,细节很烦,很码 维护区间翻转和区间赋值标记 当打到区间赋值标记时直接覆盖掉翻转标记 下放标记的时候先放赋值标记再放翻转标记 ...

  4. [bzoj2962]序列操作_线段树_区间卷积

    序列操作 bzoj-2962 题目大意:给定一个n个数的正整数序列,m次操作.支持:1.区间加:2.区间取相反数:3.区间求选c个数的乘积和. 注释:$1\le n,m\le 5\cdot 10^4$ ...

  5. 2019.01.04 bzoj2962: 序列操作(线段树+组合数学)

    传送门 线段树基础题. 题意:要求维护区间区间中选择ccc个数相乘的所有方案的和(c≤20c\le20c≤20),支持区间加,区间取负. 由于c≤20c\le20c≤20,因此可以对于每个线段树节点可 ...

  6. [SCOI2010]序列操作 BZOJ1858 线段树

    题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...

  7. BZOJ1858 [Scoi2010]序列操作(线段树)

    题目链接 [Scoi2010]序列操作 考验代码能力的一道好题. 思想还是很简单的(直接上线段树),但是比较难写. #include <bits/stdc++.h> using names ...

  8. bzoj1858SCOI 序列操作 (线段树)

    题目大意: 给定一个长度为n的01序列为,现在有m种操作 \(0\ a\ b\) 把\([a,b]\)的数全部修改为0 \(1\ a\ b\) 把\([a,b]\)的数全部修改为1 \(2\ a\ b ...

  9. BZOJ_2962_序列操作_线段树

    Description 有一个长度为n的序列,有三个操作1.I a b c表示将[a,b]这一段区间的元素集体增加c,2.R a b表示将[a,b]区间内所有元素变成相反数,3.Q a b c表示询问 ...

随机推荐

  1. 简单poi创建execl

    Workbook workbook = new HSSFWorkbook();// 创建一个Excel文件 Workbook workbook = new XSSFWorkbook();// 创建一个 ...

  2. linux 系统centOS 7 怎么在线安装mysql

    以下操作,注意空格,为避免出错,可以选择直接copy 第一步: 输入命令行      yum list installed | grep mysql       检查是否已经安装mysql 已安装输入 ...

  3. 用calc()绘制手机图案解锁的九宫格样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 通过Django Channels设计聊天机器人WEB框架

    这两个月都在忙着设计针对银联客服业务的智能聊天机器人,上一周已经交完设计报告,这一周还和部门同事一起分享了系统设计及运行效果.因为时间的关系,系统原型我使用了Flask+jQuery的组合,感觉用以原 ...

  5. SOFA 源码分析 — 调用方式

    前言 SOFARPC 提供了多种调用方式满足不同的场景. 例如,同步阻塞调用:异步 future 调用,Callback 回调调用,Oneway 调用. 每种调用模式都有对应的场景.类似于单进程中的调 ...

  6. node八-核心模块、包

    学会查API,远比会几个API更重要. 核心模块意义 -如果只是在服务器运行javascript代码,并没有多大意义,因为无法实现任何功能>读写文件.访问网络 -Node的用处在于它本身还提供可 ...

  7. Java容器:Map

    1. Map概述 1.1. Map类的继承关系 1.2. 几个Map接口类概念 1.3. Map类的通用方法 2. HashMap 2.1. 构造函数 2.2. 数据结构 2.3. 存储实现 3. H ...

  8. 浅谈C++ STL中的优先队列(priority_queue)

    从我以前的博文能看出来,我是一个队列爱好者,很多并不是一定需要用队列实现的算法我也会采用队列实现,主要是由于队列和人的直觉思维的一致性导致的. 今天讲一讲优先队列(priority_queue),实际 ...

  9. String 类的函数实现

    #include<iostream> //#include<string> using namespace std; class Strings { public: Strin ...

  10. FastDFS单机版安装

    FastDFS 分布式文件系统 1 目标 了解项目中使用FastDFS的原因和意义. 掌握FastDFS的架构组成部分,能说出tracker和storage的作用. 了解FastDFS+nginx上传 ...