zoukankan      html  css  js  c++  java
  • 【BZOJ2962】序列操作 线段树

    【BZOJ2962】序列操作

    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)。

    题解:线段树套路题。对于线段树上的每个节点都维护s[i]表示当前区间取出i个数的所有方案的和,然后区间合并的时候就是求卷积,区间取反的时候就是将奇数位取反,区间加的时候比较麻烦,用组合数搞一搞就行了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define lson x<<1
    #define rson x<<1|1
    using namespace std;
    typedef long long ll;
    const ll P=19940417;
    const int maxn=50010;
    int n,m;
    ll C[maxn][22];
    int v[maxn];
    char str[5];
    struct node
    {
    	ll ts;
    	int tf,siz;
    	ll a[21];
    	ll & operator [] (int b) {return a[b];}
    	node () {memset(a,0,sizeof(a)),ts=tf=siz=0;}
    	node operator + (node b)
    	{
    		node c;
    		register int i,j;
    		for(i=0;i<=20;i++)	for(j=0;i+j<=20;j++)	c[i+j]=(c[i+j]+a[i]*b[j])%P;
    		c.siz=siz+b.siz;
    		return c;
    	}
    	inline void rev()
    	{
    		for(register int i=1;i<20;i+=2)	a[i]=(P-a[i])%P;
    		ts=(P-ts)%P,tf^=1;
    	}
    	inline void add(ll x)
    	{
    		ts=(ts+x)%P;
    		register int i,j;
    		register ll y;
    		for(i=min(20,siz);i;i--)
    		{
    			for(y=x,j=1;j<i;y=y*x%P,j++)	a[i]=(a[i]+y*a[i-j]%P*C[siz-i+j][j])%P;
    			a[i]=(a[i]+C[siz][i]*y)%P;
    		}
    	}
    }s[maxn<<2];
    inline void pushdown(int x)
    {
    	if(s[x].tf)	s[lson].rev(),s[rson].rev(),s[x].tf=0;
    	if(s[x].ts)	s[lson].add(s[x].ts),s[rson].add(s[x].ts),s[x].ts=0;
    }
    void build(int l,int r,int x)
    {
    	if(l==r)
    	{
    		s[x].siz=s[x][0]=1,s[x][1]=v[l];
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(l,mid,lson),build(mid+1,r,rson);
    	s[x]=s[lson]+s[rson];
    }
    void up1(int l,int r,int x,int a,int b,ll c)
    {
    	if(a<=l&&r<=b)
    	{
    		s[x].add(c);
    		return ;
    	}
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(a<=mid)	up1(l,mid,lson,a,b,c);
    	if(b>mid)	up1(mid+1,r,rson,a,b,c);
    	s[x]=s[lson]+s[rson];
    }
    void up2(int l,int r,int x,int a,int b)
    {
    	if(a<=l&&r<=b)
    	{
    		s[x].rev();
    		return ;
    	}
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(a<=mid)	up2(l,mid,lson,a,b);
    	if(b>mid)	up2(mid+1,r,rson,a,b);
    	s[x]=s[lson]+s[rson];
    }
    node query(int l,int r,int x,int a,int b)
    {
    	if(a<=l&&r<=b)	return s[x];
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(b<=mid)	return query(l,mid,lson,a,b);
    	if(a>mid)	return query(mid+1,r,rson,a,b);
    	return query(l,mid,lson,a,b)+query(mid+1,r,rson,a,b);
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a,b,c;
    	for(i=0;i<=n;i++)
    	{
    		C[i][0]=1;
    		for(j=1;j<=min(i,20);j++)	C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
    	}
    	for(i=1;i<=n;i++)	v[i]=rd()%P;
    	build(1,n,1);
    	for(i=1;i<=m;i++)
    	{
    		scanf("%s",str),a=rd(),b=rd();
    		if(str[0]=='I')	c=rd(),up1(1,n,1,a,b,(c+P)%P);
    		if(str[0]=='R')	up2(1,n,1,a,b);
    		if(str[0]=='Q')	c=rd(),printf("%lld
    ",(query(1,n,1,a,b).a[c]+P)%P);
    	}
    	return 0;
    }//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 
  • 相关阅读:
    linux 安装软件三种方法
    megalo -- 网易考拉小程序解决方案
    层叠上下文 Stacking Context
    关于document.write
    学习块格式化上下文(BlockFormattingContext)
    jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
    简化版的Flappy Bird开发过程(不使用第三方框架)
    jQuery 源码分析 7: sizzle
    jQuery 源码分析6: jQuery 基本静态方法(二)
    jQuery 源码分析5: jQuery 基本静态方法(一)
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7709624.html
Copyright © 2011-2022 走看看