bzoj 2962 序列操作
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
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
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
我写的题解看这里的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 序列操作的更多相关文章
- [bzoj]2962序列操作
[bzoj]2962序列操作 标签: 线段树 题目链接 题意 给你一串序列,要你维护三个操作: 1.区间加法 2.区间取相反数 3.区间内任意选k个数相乘的积 题解 第三个操作看起来一脸懵逼啊. 其实 ...
- bzoj 2962 序列操作——线段树(卷积?)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2962 如果 _,_,_,…… 变成了 (_+k),(_+k),(_+k),…… ,计算就是在 ...
- bzoj 2962 序列操作 —— 线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2962 维护 sum[i] 表示选 i 个的乘积和,合并两个子树就枚举两边选多少,乘起来即可: ...
- bzoj 1858 序列操作
bzoj 1858 序列操作 带有随机多个区间单值覆盖的区间操作题,可考虑用珂朵莉树解决. #include<bits/stdc++.h> using namespace std; #de ...
- 【BZOJ-2962】序列操作 线段树 + 区间卷积
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 678 Solved: 246[Submit][Status][Discuss] ...
- BZOJ 2962
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 618 Solved: 225[Submit][Status][Discuss] ...
- bzoj2962 序列操作
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 1145 Solved: 378[Submit][Status][Discuss ...
- (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...
- bzoj 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...
随机推荐
- mybatis快速入门(八)-spring-mybatis动态代理整合
将上一节的代码改造下就好了,不过这一章会加一个basedaomapper.废话不多说直接上代码了. 创建一个BaseDaoMapper.java package cn.my.sm.mapper; /* ...
- 【NOIP2012】【CJOJ1093】【洛谷1083】借教室
我写的是不完美算法!!! 题面 Description 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的 ...
- Luogu3242:[HNOI2015]接水果
题面 Luogu3242 Sol 考虑每个盘子怎样才能接到一个水果 分两种情况: 盘子的\(x, y\)在一条链上,那么水果的两点就要在这条链之外 不在的话,水果的两点就分别在盘子的两点的子树中 记录 ...
- 浅析Unity中的Enlighten与混合光照
0x00 前言 在Unity的5.6版本之前的5.x中,主要使用了Geomerics公司的Enlighten[1]来提供实时全局照明以及烘焙全局照明,在5.6之后Unity引入了新的Lightmapp ...
- 小程序input输入框获取焦点时,文字会出现闪动
最近在开发小程序时,发现一个有趣的现象.input里面设置了placeholder,随后当输入框获取焦点时,文字会出现一瞬间的抖动,随后正常. 猜想可能是设置的font-family不同引起的抖动,但 ...
- 自增ID算法snowflake(雪花)
在数据库主键设计上,比较常见的方法是采用自增ID(1开始,每次加1)和生成GUID.生成GUID的方式虽然简单,但是由于采用的是无意义的字符串,推测会在数据量增大时造成访问过慢,在基础互联网的系统设计 ...
- 大数据量情况下高效比较两个list
比如,对两个list<object>进行去重,合并操作时,一般的写法为两个for循环删掉一个list中重复的,然后再合并. 如果数据量在千条级别,这个速度还是比较快的.但如果数据量超过20 ...
- Spring(十二)Spring之事务
java中事务是什么? 事务是访问数据库的一个操作序列,DB应用系统通过事务集来完成对数据的存取. 事务必须遵循4个原则,即常说的 ACID A,Automicity,原子性,即事务要么被全部执行,要 ...
- AOP面向切面编程在Android中的使用
GitHub地址(欢迎下载完整Demo) https://github.com/ganchuanpu/AOPDemo 项目需求描述 我想类似于这样的个人中心的界面,大家都不会陌生吧.那几个有箭头的地方 ...
- js实现二叉树
//binary tree//add order remove findfunction tree() { var node = function(key) { this.left = null; ...