2962: 序列操作

Time Limit: 50 Sec  Memory Limit: 256 MB
[Submit][Status][Discuss]

Description

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

Input

  第一行两个数n,q表示序列长度和操作个数。
  第二行n个非负整数,表示序列。
  接下来q行每行输入一个操作I a b c或者 R a b或者Q a b c意义如题目描述。

Output

  对于每个询问,输出选出c个数相乘的所有方案的和mod19940417的值。

Sample Input

5 5
1 2 3 4 5
I 2 3 1
Q 2 4 2
R 1 5
I 1 3 -1
Q 1 5 1

Sample Output

40
19940397
样例说明
  做完第一个操作序列变为1 3 4 4 5。
  第一次询问结果为3*4+3*4+4*4=40。
  做完R操作变成-1 -3 -4 -4 -5。
  做完I操作变为-2 -4 -5 -4 -5。
  第二次询问结果为-2-4-5-4-5=-20。

HINT

  100%的数据n<=50000,q<=50000,初始序列的元素的绝对值<=109,I a b c中保证[a,b]是一个合法区间,|c|<=109,R a b保证[a,b]是个合法的区间。Q a b c中保证[a,b]是个合法的区间1<=c<=min(b-a+1,20)。

Source

中国国家队清华集训 2012-2013 第三天

我写的题解看这里的T2

http://www.cnblogs.com/TheRoadToTheGold/p/7723564.html

网上的参考题解

http://blog.csdn.net/werkeytom_ftd/article/details/51767696

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 50001 const int mod=; typedef long long LL; int n; int C[N][]; int f[N<<];
int siz[N<<],mid[N<<];
bool rev[N<<]; struct node { int sum[]; }ans[N<<]; void read(int &x)
{
x=; int ff=; char c=getchar();
while(!isdigit(c)) { if(c=='-') ff=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=ff;
} int tot=; void MOD(int &a,int b)
{
a+=b;
a-= a>=mod ? mod : ;
} void pre(int n)
{
C[][]=;
for(int i=;i<=n;i++)
{
C[i][]=;
for(int j=;j<=min(i,);j++) C[i][j]=(C[i-][j]+C[i-][j-])%mod;
}
} void update(int k)
{
for(int i=;i<=;i++)
{
ans[k].sum[i]=;
for(int j=;j<i;j++) MOD(ans[k].sum[i],1ll*ans[k<<].sum[j]*ans[k<<|].sum[i-j]%mod);
MOD(ans[k].sum[i],ans[k<<].sum[i]); MOD(ans[k].sum[i],ans[k<<|].sum[i]);
}
} void build(int k,int l,int r)
{
siz[k]=r-l+;
if(l==r) { read(ans[k].sum[]); MOD(ans[k].sum[],); return; }
mid[k]=l+r>>;
build(k<<,l,mid[k]); build(k<<|,mid[k]+,r);
update(k);
} void insert(int k,int w)
{
MOD(f[k],w);
for(int i=;i;i--)
{
int x=w;
for(int j=i-;j;j--,x=1ll*x*w%mod)
MOD(ans[k].sum[i],1ll*x*ans[k].sum[j]%mod*C[siz[k]-j][i-j]%mod);
MOD(ans[k].sum[i],1ll*x*C[siz[k]][i]%mod);
}
} void turn(int k)
{
rev[k]^=;
if(f[k]) f[k]=mod-f[k];
for(int i=;i>;i-=)
if(ans[k].sum[i]) ans[k].sum[i]=mod-ans[k].sum[i];
} void down(int k)
{
if(rev[k]) turn(k<<),turn(k<<|),rev[k]=;
if(f[k]) insert(k<<,f[k]),insert(k<<|,f[k]),f[k]=;
} void add(int k,int l,int r,int opl,int opr,int w)
{
if(l>=opl && r<=opr) { insert(k,w); return; }
down(k);
if(opl<=mid[k]) add(k<<,l,mid[k],opl,opr,w);
if(opr>mid[k]) add(k<<|,mid[k]+,r,opl,opr,w);
update(k);
} void reverse(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr) { turn(k); return; }
down(k);
if(opl<=mid[k]) reverse(k<<,l,mid[k],opl,opr);
if(opr>mid[k]) reverse(k<<|,mid[k]+,r,opl,opr);
update(k);
} node query(int k,int l,int r,int opl,int opr,int w)
{
if(l>=opl && r<=opr) return ans[k];
down(k);
if(opr<=mid[k]) return query(k<<,l,mid[k],opl,opr,w);
else if(opl>mid[k]) return query(k<<|,mid[k]+,r,opl,opr,w);
else
{
node L=query(k<<,l,mid[k],opl,opr,w),R=query(k<<|,mid[k]+,r,opl,opr,w);
node tmp;
for(int i=;i<=w;i++)
{
tmp.sum[i]=(L.sum[i]+R.sum[i])%mod;
for(int j=;j<i;j++) MOD(tmp.sum[i],1ll*L.sum[j]*R.sum[i-j]%mod);
}
return tmp;
}
} int main()
{
int n,m; char c[];
read(n); read(m);
pre(n);
build(,,n);
int l,r,w;
while(m--)
{
scanf("%s",c); read(l); read(r);
if(c[]=='I')
{
read(w); w%=mod;
w+= w< ? mod : ;
add(,,n,l,r,w);
}
else if(c[]=='R') reverse(,,n,l,r);
else
{
read(w);
node p=query(,,n,l,r,w);
printf("%d\n",query(,,n,l,r,w).sum[w]);
}
}
}

bzoj 2962 序列操作的更多相关文章

  1. [bzoj]2962序列操作

    [bzoj]2962序列操作 标签: 线段树 题目链接 题意 给你一串序列,要你维护三个操作: 1.区间加法 2.区间取相反数 3.区间内任意选k个数相乘的积 题解 第三个操作看起来一脸懵逼啊. 其实 ...

  2. bzoj 2962 序列操作——线段树(卷积?)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2962 如果 _,_,_,…… 变成了 (_+k),(_+k),(_+k),…… ,计算就是在 ...

  3. bzoj 2962 序列操作 —— 线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2962 维护 sum[i] 表示选 i 个的乘积和,合并两个子树就枚举两边选多少,乘起来即可: ...

  4. bzoj 1858 序列操作

    bzoj 1858 序列操作 带有随机多个区间单值覆盖的区间操作题,可考虑用珂朵莉树解决. #include<bits/stdc++.h> using namespace std; #de ...

  5. 【BZOJ-2962】序列操作 线段树 + 区间卷积

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 678  Solved: 246[Submit][Status][Discuss] ...

  6. BZOJ 2962

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 618  Solved: 225[Submit][Status][Discuss] ...

  7. bzoj2962 序列操作

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 1145  Solved: 378[Submit][Status][Discuss ...

  8. (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作

    二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...

  9. bzoj 1858: [Scoi2010]序列操作

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...

随机推荐

  1. Java注解学习

    一.注解定义 JVM5.0定义了4个标准的元注解: @Target, @Retention, @Documented @Inherited 1. @Target 作用:用于描述注解的使用范围 取值El ...

  2. springmvc结合ajax的分页功能

    var itemCount;//符合查找条件的商品总页数,分页参考 var pageIndex = 0;//当前页,默认为0 var pageSize = 8;//每页显示个数为8 //按条件查找用户 ...

  3. 关于设计SQL表的一些问题

    1.设计问题: 当sql语句输入时,需要输入表名,表名内需要输入日期,而且譬如"第二天安装"这种,sql语句中有两个地方需要输入日期,一个是昨天,一个是今天,这种情况将输入日期的部 ...

  4. Java仪器数据文件解析-PDF文件

    一.概述 使用pdfbox可生成Pdf文件,同样可以解析PDF文本内容. pdfbox链接:https://pdfbox.apache.org/ 二.PDF文本内容解析 File file = new ...

  5. Java设计模式(六)Adapter适配器模式

    一.场景描述 “仪器数据采集器”包含采集数据以及发送数据给服务器两行为,则可定义“仪器数据采集器”接口,定义两方法“采集数据capture”和“发送数据sendData”. “PDF文件数据采集器”实 ...

  6. WebGL 3D 电信机架实战之数据绑定

    前言 在前端中,视图层和数据层需要进行单向或者双向数据绑定,大家都已经不陌生了,有时候 2D 做的比较顺了之后,就会想要挑战一下 3D,不然总觉得痒痒的.这个 3D 机架的 Demo 我觉得非常有代表 ...

  7. leetCode:237 删除链表的结点

    删除链表的结点 编写一个函数,在给定单链表一个结点(非尾结点)的情况下,删除该结点. 假设该链表为1 -> 2 -> 3 -> 4 并且给定你链表中第三个值为3的节点,在调用你的函数 ...

  8. C语言第一次博客作业

    一,PTA实验作业 题目1.温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代 ...

  9. [Luogu 1395] 会议

    题目 Description 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那 ...

  10. Maven-01: Maven入门

    先看看开发环境: 我们在E盘下新建一个文件夹叫helloworld,这个文件夹下建一个src文件夹和一个文件pom.xml. src下的目录结构为: pom.xml文件内容为: <?xml ve ...