60TLE
把要求信息拆分 用 线段树和矩阵维护
upd:fqk太劲了 加个读入优化就A过去了
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=5e5+10;
const int LOGN=5e5*4+10;
#define float double
struct H{float j1,j2,j3,j4,s0,s1,L,R;};
int n,m;
float num[LOGN];
H jj[LOGN];
H f(H a,H b){return (H){a.j1*b.j1,a.j1*b.j2+a.j2,a.j3*b.j1+b.j3,a.j3*b.j2+a.j4+b.j4,a.s0+b.s0,a.s1+b.s1-a.R*b.L,a.L,b.R};}
int mi[MAXN];
inline double sc()
{
char c=getchar();
double z=0,x=0;
int cc=0;
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') {z=z*10+c-'0'; c=getchar();}
if (c=='.')
{
c=getchar();
while (c>='0'&&c<='9') {x=x*10+c-'0'; cc++; c=getchar();}
return z+x/mi[cc];
}
return z;
}
inline void build(int now,int l,int r)
{
if(l==r)
{
jj[now]=(H){num[l],2*num[l],num[l],num[l],num[l],num[l],num[l],num[l]};
return ;
}
int mid=(l+r)/2;
build(now*2,l,mid);build(now*2+1,mid+1,r);
jj[now]=f(jj[now*2],jj[now*2+1]);
}
inline H q(int now,int l,int r,int s,int t)
{
if(s<=l&&r<=t)
{
return jj[now];
}
H ans;bool ok=false;int mid=(l+r)/2;
if(s<=mid) ok=true,ans=q(now*2,l,mid,s,t);
if(mid+1<=t) if(ok) ans=f(ans,q(now*2+1,mid+1,r,s,t)); else ans=q(now*2+1,mid+1,r,s,t);
return ans;
}
inline void change(int now,int l,int r,int loc)
{
if(l==r)
{
jj[now]=(H){num[l],2*num[l],num[l],num[l],num[l],num[l],num[l],num[l]};
return ;
}
int mid=(l+r)/2;
if(loc<=mid) change(now*2,l,mid,loc);
else change(now*2+1,mid+1,r,loc);
jj[now]=f(jj[now*2],jj[now*2+1]);
}
int main()
{
// freopen("shell.in","r",stdin);
// freopen("shell.out","w",stdout);
mi[0]=1;
for(int i=1;i<=10;i++) mi[i]=mi[i-1]*10;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) num[i]=sc();//scanf("%lf",&num[i]);
build(1,1,n);
int opt,x,y;float now;
while(m--)
{
scanf("%d",&opt);
if(opt==0)
{
//scanf("%d %d",&x,&y);
x=sc();y=sc();
H ans=q(1,1,n,x,y);
printf("%.2lf\n",ans.j4+ans.s0+ans.s1);
}
else
{
//scanf("%d %lf",&x,&now);
x=sc();now=sc();
num[x]=now;
change(1,1,n,x);
}
}
return 0;
}