• HDU 4578 Transformation


    Time limit 8000 ms
    Memory limit 65536 kB
    OS Windows
    Source 2013ACM-ICPC杭州赛区全国邀请赛

    感想

    线段树加法乘法大合集,有了这些操作,其他的区间平均值、区间方差什么的都不是事儿了。和这题相比,[AHOI2009]维护序列就太简单了,只有乘法加法区间和……

    顺便,一开始不说p的大小,直到输入那里才说是想吓死人啊。

    解题思路

    和维护序列那题一样,依然从标记之间的关系来看,推一推公式,看一个操作对该区间的其他标记、总和、平方和、立方和的影响。

    时间不早了,扔两个链接,去睡了敷衍

    垃圾CSDN,开始封禁博客园链接了,急了吧,让你之前设计反人类,让你广告恶心人,活该用户变少

    源代码

    我这代码仿佛在打表

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    const long long mod=10007;
    int T;
    int n,m;
    struct Node{
    	int l,r;
    	long long lazyadd,lazymul,lazyset;
    	//0,1,-1.设置set标记时,马上清空add、mul。下放时,如果三个都有,说明是在set之后放的
    	long long sum[4];
    }t[400010];
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    
    void build(int x,int l,int r)
    {
    	memset(&t[x],0,sizeof(t[x]));
    	t[x].l=l;
    	t[x].r=r;
    	t[x].lazymul=1;
    	t[x].lazyset=-1;
    	if(l==r) return;
    	int mid=l+r>>1;
    	build(ls(x),l,mid);
    	build(rs(x),mid+1,r);
    }
    
    inline void pushdown(int x)
    {
    	if(~t[x].lazyset)
    	{
    		long long b=t[x].lazyset%mod;
    		t[x].lazyset=-1;
            int len=t[ls(x)].r-t[ls(x)].l+1;
    		t[ls(x)].sum[1]=len*b%mod;
    		t[ls(x)].sum[2]=len*b%mod*b%mod;
    		t[ls(x)].sum[3]=len*b%mod*b*b%mod;
    		len=(t[rs(x)].r-t[rs(x)].l+1);
    		t[rs(x)].sum[1]=len*b%mod;
    		t[rs(x)].sum[2]=len*b%mod*b%mod;
    		t[rs(x)].sum[3]=len*b%mod*b*b%mod;
    		t[ls(x)].lazyset=t[rs(x)].lazyset=b;
    		t[ls(x)].lazyadd=t[rs(x)].lazyadd=0;
    		t[ls(x)].lazymul=t[rs(x)].lazymul=1;
    	}
    	if(t[x].lazymul!=1)
    	{
    		long long b = t[x].lazymul%mod;
    		t[x].lazymul = 1;
    
    		t[ls(x)].lazyadd*=b;t[ls(x)].lazyadd%=mod;
    		t[ls(x)].lazymul*=b;t[ls(x)].lazymul%=mod;
    		t[ls(x)].sum[1]*=b;
    		t[ls(x)].sum[2]*=b*b%mod;
    		t[ls(x)].sum[3]*=b*b%mod*b;
    		t[ls(x)].sum[1]%=mod;
    		t[ls(x)].sum[2]%=mod;
    		t[ls(x)].sum[3]%=mod;
    
    		t[rs(x)].lazyadd*=b;t[rs(x)].lazyadd%=mod;
    		t[rs(x)].lazymul*=b;t[rs(x)].lazymul%=mod;
    		t[rs(x)].sum[1]*=b;
    		t[rs(x)].sum[2]*=b*b%mod;
    		t[rs(x)].sum[3]*=b*b%mod*b;
    		t[rs(x)].sum[1]%=mod;
    		t[rs(x)].sum[2]%=mod;
    		t[rs(x)].sum[3]%=mod;
    	}
    	if(t[x].lazyadd)
    	{
    		long long b=t[x].lazyadd;//////顺序321
    		t[x].lazyadd=0;
    		int len=t[ls(x)].r-t[ls(x)].l+1;
    		t[ls(x)].sum[3]+=len*b%mod*b*b%mod+t[ls(x)].sum[1]*b%mod*b*3%mod+t[ls(x)].sum[2]*b*3%mod;
    		t[ls(x)].sum[2]+=len*b%mod*b%mod+t[ls(x)].sum[1]*b*2%mod;
    		t[ls(x)].sum[1]+=len*b%mod;
    		t[ls(x)].sum[1]%=mod;
    		t[ls(x)].sum[2]%=mod;
    		t[ls(x)].sum[3]%=mod;
    		t[ls(x)].lazyadd+=b;t[ls(x)].lazyadd%=mod;
    		len=t[rs(x)].r-t[rs(x)].l+1;
    		t[rs(x)].sum[3]+=len*b%mod*b*b%mod+t[rs(x)].sum[1]*b%mod*b*3%mod+t[rs(x)].sum[2]*b*3%mod;
    		t[rs(x)].sum[2]+=len*b%mod*b%mod+t[rs(x)].sum[1]*b*2%mod;
    		t[rs(x)].sum[1]+=len*b%mod;
    		t[rs(x)].sum[1]%=mod;
    		t[rs(x)].sum[2]%=mod;
    		t[rs(x)].sum[3]%=mod;
    		t[rs(x)].lazyadd+=b;t[rs(x)].lazyadd%=mod;
    	}
    }
    
    inline void pushup(int x)
    {
    	t[x].sum[1]=(t[ls(x)].sum[1]+t[rs(x)].sum[1])%mod;
    	t[x].sum[2]=(t[ls(x)].sum[2]+t[rs(x)].sum[2])%mod;
    	t[x].sum[3]=(t[ls(x)].sum[3]+t[rs(x)].sum[3])%mod;
    }
    
    void add(int x,int l,int r,long long k)
    {
    	if(l<=t[x].l&&t[x].r<=r)
    	{
    		t[x].lazyadd+=k;
    		t[x].lazyadd%=mod;
    		int len=t[x].r-t[x].l+1;
    		t[x].sum[3]+=3*k*t[x].sum[2]%mod+3*k*k%mod*t[x].sum[1]%mod+len*k%mod*k*k%mod;
    		t[x].sum[2]+=2*k*t[x].sum[1]%mod+len*k%mod*k%mod;
    		t[x].sum[1]+=len*k%mod;
    		t[x].sum[1]%=mod;
    		t[x].sum[2]%=mod;
    		t[x].sum[3]%=mod;
    		return;
    	}
    	int mid=t[x].l+t[x].r>>1;
    	pushdown(x);
    	if(l<=mid) add(ls(x),l,r,k);
    	if(r>mid) add(rs(x),l,r,k);
    	pushup(x);
    }
    
    void mult(int x,int l,int r,long long k)
    {
    	if(l<=t[x].l&&t[x].r<=r)
    	{
    		t[x].lazymul*=k;
    		t[x].lazymul%=mod;
    		t[x].lazyadd*=k;//第一次交题的时候这步操作漏了,打乘法标记的时候记得把加法标记也乘一下
    		t[x].lazyadd%=mod;
    		t[x].sum[3]*=k*k%mod*k%mod;
    		t[x].sum[2]*=k*k%mod;
    		t[x].sum[1]*=k;
    		t[x].sum[1]%=mod;
    		t[x].sum[2]%=mod;
    		t[x].sum[3]%=mod;
    		return;
    	}
    	int mid=t[x].l+t[x].r>>1;
    	pushdown(x);
    	if(l<=mid) mult(ls(x),l,r,k);
    	if(r>mid) mult(rs(x),l,r,k);
    	pushup(x);
    }
    
    void change(int x,int l,int r,long long k)
    {
    	if(l<=t[x].l&&t[x].r<=r)
    	{
    		int len=t[x].r-t[x].l+1;
    		t[x].lazyset=k,t[x].lazyadd=0,t[x].lazymul=1;
    		t[x].sum[3]=len*k%mod*k*k%mod;
    		t[x].sum[2]=len*k%mod*k%mod;
    		t[x].sum[1]=len*k%mod;
    		return;
    	}
    	int mid=t[x].l+t[x].r>>1;
    	pushdown(x);
    	if(l<=mid) change(ls(x),l,r,k);
    	if(r>mid) change(rs(x),l,r,k);
    	pushup(x);
    }
    
    long long que(int x,int l,int r,long long p)
    {
    	if(l<=t[x].l&&t[x].r<=r)
    	{
    		return t[x].sum[p];
    	}
    	int mid=t[x].l+t[x].r>>1;
    	pushdown(x);
    	long long ans=0;
    	if(l<=mid) ans+=que(ls(x),l,r,p);
    	if(r>mid) ans+=que(rs(x),l,r,p);
    	return ans%mod;
    }
    
    int main()
    {
    	while((scanf("%d%d",&n,&m),n||m))
    	{
    		build(1,1,n);
    		int opt,a,b;
    		long long c;
    		while(m--)
    		{
    			scanf("%d%d%d%I64d",&opt,&a,&b,&c);//这题是Windows系统
    			if(opt==1)
    				add(1,a,b,c);
    			else if(opt==2)
    				mult(1,a,b,c);
    			else if(opt==3)
    				change(1,a,b,c);
    			else if(opt==4)
    				printf("%I64d
    ",que(1,a,b,c));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    人工智能正在跨越“恐怖谷”,未来或将善恶共存
    大数据可视化的途径
    数据科学家公司生存指南TOP30秘诀
    真真假假?专访七位AI专家,辨析医疗人工智能真伪
    大数据主要应用于哪些行业,应用价值是什么?
    【人工智能】 火爆的机器学习和人工智能,为何在金融业四处碰壁?
    大数据时代,你是否拥有「文科思维」?
    AI和企业管理
    刷脸新时代:我国人工智能技术世界领先 产业规模3600亿元
    交待给你的事办完了,就不能回个话么?
  • 原文地址:https://www.cnblogs.com/wawcac-blog/p/11267455.html
Copyright © 2020-2023  润新知