• Luogu P3655 不成熟的梦想家 (未熟DREAMER)



    Luogu P3655 不成熟的梦想家 (未熟DREAMER)

    解析

    • 记录差分数组,每次修改差分值即可
    • 对被修改的位置先减去它之前的贡献,然后修改它的值,然后加上它之后的贡献

    Code

    法一(树状数组 $ Theta (nlogn) $ )

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int N=2e5+5;
    int n,q;
    LL s,t,b,now,last,ctr[N];
    int lowbit(int u)
    {
    	return u&(-u);
    }
    void update(int u,LL v)
    {
    	for(;u<=n;u+=lowbit(u)) ctr[u]+=v;
    	return;
    }
    LL query(int u)
    {
    	LL res=0;
    	for(;u;u-=lowbit(u)) res+=ctr[u];
    	return res;
    }
    int main()
    {
    	scanf("%d%d%lld%lld%lld",&n,&q,&s,&t,&now);	
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&now);
    		if(now>last) b-=s*(now-last);
    		if(now<last) b+=t*(last-now);
    		update(i,now-last);
    		last=now;
    	}
    	while(q--)
    	{
    		int x,y;
    		LL z;
    		scanf("%d%d%lld",&x,&y,&z);
    		LL l1=query(x-1),l2=query(x);
    		if(l2>l1) b+=s*(l2-l1);
    		if(l2<l1) b-=t*(l1-l2);
    		update(x,z);
    		l1=query(x-1),l2=query(x);
    		if(l2>l1) b-=s*(l2-l1);
    		if(l2<l1) b+=t*(l1-l2);
    		if(y==n)
    		{
    			printf("%lld
    ",b);
    			continue;
    		}
    		LL r1=query(y),r2=query(y+1);
    		if(r2>r1) b+=s*(r2-r1);
    		if(r2<r1) b-=t*(r1-r2);
    		update(y+1,-z);
    		r1=query(y),r2=query(y+1);
    		if(r2>r1) b-=s*(r2-r1);
    		if(r2<r1) b+=t*(r1-r2);
    		printf("%lld
    ",b);
    	}
    	return 0;
    }
    

    法二(差分 $ Theta (n) $ )

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int N=2e5+5;
    int n,q;
    LL s,t,b,a[N],c[N];
    int main()
    {
    	scanf("%d%d%lld%lld%lld",&n,&q,&s,&t,&a[0]);	
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&a[i]);
    		c[i]=a[i]-a[i-1];
    		if(c[i]>0) b-=s*c[i];
    		if(c[i]<0) b+=t*(-c[i]);
    	}
    	while(q--)
    	{
    		int x,y;
    		LL z;
    		scanf("%d%d%lld",&x,&y,&z);
    		if(c[x]>0) b+=s*c[x];
    		if(c[x]<0) b-=t*(-c[x]);
    		c[x]+=z;
    		if(c[x]>0) b-=s*c[x];
    		if(c[x]<0) b+=t*(-c[x]);
    		if(y==n)
    		{
    			printf("%lld
    ",b);
    			continue;
    		}
    		if(c[y+1]>0) b+=s*c[y+1];
    		if(c[y+1]<0) b-=t*(-c[y+1]);
    		c[y+1]-=z;
    		if(c[y+1]>0) b-=s*c[y+1];
    		if(c[y+1]<0) b+=t*(-c[y+1]);
    		printf("%lld
    ",b);
    	}
    	return 0;
    }
    
  • 相关阅读:
    OpenWAF学习笔记(四)—— API-接入规则
    OpenWAF学习笔记(三)—— 调用API时403?
    OpenWAF学习笔记(二)—— 入门
    OpenWAF学习笔记(一)—— 安装
    SQL Server获取数据库表、视图、存储过程数量及名称
    获取真实IP地址——代理背后的终端ip地址
    博客园美化-添加看板娘
    强密码验证-大小写字母、数字、特殊字符、长度
    【c++面试总结】
    【一天一道算法题】 两个字符串相乘
  • 原文地址:https://www.cnblogs.com/Hawking-llfz/p/11595575.html
Copyright © 2020-2023  润新知