codeforces 283A

codeforces 283A

A. Cows and Sequence

introduction

这道题目的难点在于怎么在维护队列末尾的元素

method

看了官方的题解,我还是云里雾里的,最后经大神的题解点拨,才发现这道题目运用的是lazy思想。在学习线段树的时候遇到过这个思想,做这道题目的时候就没有想到,以后学习一定要透彻。

引用一下大神的解释:

A.比较简单,操作时候一直维护总和就可以了。。对于操作1(前a个数全部增加x)以及操作2(添加一个新数字在队列最后)显然可以顺利做到,而操作3则要求求出当前队列最后数字的值,我们可以用lasy的思想处理操作1即可以,如在head ~head+a 的位置增加x,我们可以在head+a的位置记录这个x(mark[head+ai]+=x),当head+a被删除之后后,才会要求求出head+ai-1位置的值,所以在删除head+a后我们将记录在该位置上的x值传到上一位即可(mark[head+a-1] += mark[head+a])..时间空间复杂度均O(n)

tips

  • lazy技术应用的关键点在于属性值的变化在射线方向传播
  • lazy数组要及时清零,或者说要保持正确的状态

Q&A

conclusion

一个算法往往体现了一种思想,不仅要学习算法的流程,更要体会算法的思想。

reference

http://www.cnblogs.com/lzqxh/archive/2013/03/19/2969723.html

code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<istream>
#include<cassert>
#include<set>
#include<iomanip>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
#define DEBUG2(x,y) cout<<#x<<" = "<<x<<" , "\
<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
const int MAXN=2e5+10;
double sum=0;
int pos=1;
int seq[MAXN];
///延迟技术
///在一个方向上变化的,容易实现延迟
int lazy[MAXN];
double delta(int op,int a,int x)
{
    if(op==1){
        lazy[a-1]+=x;
        return a*x*1.0;
    }
    else if(op==2){
        ///lazy要清零
        lazy[pos]=0;
        seq[pos++]=a;
        return a*1.0;
    }
    else {
        pos--;
        lazy[pos-1]+=lazy[pos];
        seq[pos]+=lazy[pos];
        return -seq[pos]*1.0;
    }
}
int main()
{
//    freopen("in.txt","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF){
        sum=0,pos=1;
        memset(lazy,0,sizeof(lazy));
        memset(seq,0,sizeof(seq));
        while (n--){
            int op=-1,a=-1,x=-1;
            scanf("%d",&op);
            if(op==1)scanf("%d%d",&a,&x);
            else if(op==2)scanf("%d",&a);
            sum+=delta(op,a,x);
            printf("%.10lf\n",sum/pos);
        }
    }
}

posted @ 2019-01-23 14:49  MalcolmMeng  阅读(238)  评论(0编辑  收藏  举报