zoukankan      html  css  js  c++  java
  • 20201019 day39 复习10:数据结构之树状数组、线段树

    1 树状数组1

    problem

    单点修改,区间求和。

    solution

    树状数组直接维护原数组。初始化的时候用changex函数直接进行修改。

    code

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int n,m,p[500005],a[500005];
    int read(){
    	int a=0,op=1;
    	char c;c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') op=-1;c=getchar();
    	}
    	while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
    	return a*op;
    }
    int lowbit(int x){
    	return x&(-x);	
    }
    void changex(int num,int x){
    	for(int i=num;i<=n;i+=lowbit(i)) a[i]+=x;
    	return ;
    }
    int findx(int x){
    	int sum=0;
    	for(int i=x;i;i-=lowbit(i)) sum+=a[i];	
    	return sum;
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) p[i]=read();
    	for(int i=1;i<=n;i++) changex(i,p[i]);
    	while(m--){
    		int b=0,x=0,y=0;
    		b=read(),x=read(),y=read();
    		if(b==1) changex(x,y);
    		if(b==2) printf("%d
    ",findx(y)-findx(x-1));
    	}
    	return 0;
    }
    

    2 树状数组2

    problem

    区间修改,单点查询。

    solution

    树状数组处理差分数组,差分数组的前缀和就是某一位的数。修改的时候,修改([x,y])其实就是第(x)位加,第(y+1)位减去。

    code

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int n,m,p[500005],a[500005];
    int read(){
    	int a=0,op=1;
    	char c;c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') op=-1;c=getchar();
    	}
    	while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
    	return a*op;
    }
    int lowbit(int x){
    	return x&(-x);	
    }
    void changex(int num,int x){
    	for(int i=num;i<=n;i+=lowbit(i)) a[i]+=x;
    	return ;
    }
    int findx(int x){
    	int sum=0;
    	for(int i=x;i;i-=lowbit(i)) sum+=a[i];	
    	return sum;
    }
    int chafen[500005];
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) p[i]=read();
    	chafen[1]=p[1];
    	for(int i=2;i<=n;i++) chafen[i]=p[i]-p[i-1];
    	for(int i=1;i<=n;i++) changex(i,chafen[i]);
    	while(m--){
    		int b=0,x=0,y=0,z=0;
    		b=read();
    		if(b==1) 
    			x=read(),y=read(),z=read(),changex(x,z),changex(y+1,-z);
    		if(b==2) x=read(),printf("%d
    ",findx(x));
    	}
    	return 0;
    }
    

    3 二维树状数组1

    loj133

    problem

    二维矩阵中,修改(A_{x,y})的值,或者查询((a,b))((c,d))之间的矩阵元素和。
    【单点修改,区间查询】

    solution

    与一维类似。使用二维前缀和。

    code

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    long long c[5005][5005];
    int n,m;
    long long read(){
    	long long a=0,op=1;
    	char c;c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') op=-1;c=getchar();
    	}
    	while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
    	return a*op;
    }
    int lowbit(int x){
    	return x&(-x);	
    }
    void changex(int x,int y,long long num){
    	for(int i=x;i<=n;i+=lowbit(i))
    		for(int j=y;j<=m;j+=lowbit(j))
    			c[i][j]+=num;
    }
    long long findx(int x,int y){
    	long long ans=0;
    	for(int i=x;i;i-=lowbit(i))
    		for(int j=y;j;j-=lowbit(j))
    			ans+=c[i][j];
    	return ans;
    }
    void subtask1(){
    	int x,y,k;
    	x=read(),y=read(),k=read();
    	changex(x,y,k);	
    }
    void subtask2(){
    	int x1,y1,x2,y2;
    	x1=read(),y1=read(),x2=read(),y2=read();
    	long long ans=findx(x2,y2)+findx(x1-1,y1-1)-findx(x1-1,y2)-findx(x2,y1-1);
    	printf("%lld
    ",ans);	
    }
    signed main(){
    	n=read(),m=read();
    	//printf("%d %d
    ",n,m);
    	int op;
    	while(~scanf("%d",&op)){
    		if(op==1) subtask1();
    		else subtask2();
    	}
    	return 0;
    }
    

    4 二维树状数组2

    loj134

    problem

    区间修改,单点查询。

    solution

    二维差分,灵魂在这里:

    void insert(int a,int b,int c,int d,int k){
    	changex(a,b,k),changex(a,d+1,-k);
    	changex(c+1,b,-k),changex(c+1,d+1,k);	
    } 
    

    code

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    long long c[5005][5005];
    int n,m;
    long long read(){
    	long long a=0,op=1;
    	char c;c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') op=-1;c=getchar();
    	}
    	while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
    	return a*op;
    }
    int lowbit(int x){
    	return x&(-x);	
    }
    void changex(int x,int y,long long num){
    	for(int i=x;i<=n;i+=lowbit(i))
    		for(int j=y;j<=m;j+=lowbit(j))
    			c[i][j]+=num;
    }
    long long findx(int x,int y){
    	long long ans=0;
    	for(int i=x;i;i-=lowbit(i))
    		for(int j=y;j;j-=lowbit(j))
    			ans+=c[i][j];
    	return ans;
    }
    void insert(int a,int b,int c,int d,int k){
    	changex(a,b,k),changex(a,d+1,-k);
    	changex(c+1,b,-k),changex(c+1,d+1,k);	
    } 
    void subtask1(){
    	int a,b,c,d,k;
    	a=read(),b=read(),c=read(),d=read(),k=read();
    	insert(a,b,c,d,k);
    }
    void subtask2(){
    	int x,y;
    	x=read(),y=read();
    	printf("%lld
    ",findx(x,y));	
    }
    int main(){
    	n=read(),m=read();
    	//printf("%d %d
    ",n,m);
    	int op;
    	while(~scanf("%d",&op)){
    		if(op==1) subtask1();
    		else subtask2();
    	}
    	return 0;
    }
    

    5 树状数组3

    problem

    区间修改,区间查询。

    solution

    考察:

    [egin{align} sum_{i=1}^na_i &= a_1+a_2+cdots +a_n \ &=d_1+(d_1+d_2)+(d_1+d_2+d_3)+cdots \ &=nd_1+(n-1)d_2+...+d_n \ &=nsum_{i=1}^nd_i -[0 imes d_1+1 imes d_2+cdots +(n-1) imes d_n)]\ end{align}]

    维护差分数组(d_i)和数组((i-1)d_i),分别进行前缀和操作。区间修改借助差分数组即可(因为两个数组都满足差分的性质)

    code

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    long long read(){
    	long long a=0,op=1;
    	char c;c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') op=-1;c=getchar();
    	}
    	while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
    	return a*op;
    }
    int lowbit(int x){
    	return x&(-x);	
    }
    const int maxn=1e7+10;
    int n,k;
    long long a[maxn],sum[maxn],c1[maxn],c2[maxn];
    void addc1(int p,long long w){
    	while(p<=n) c1[p]+=w,p+=lowbit(p);
    	return ;	
    }
    void addc2(int p,long long w){
    	while(p<=n) c2[p]+=w,p+=lowbit(p);
    	return ;	
    }
    long long askc1(int p){
    	long long ans=0;
    	while(p) ans+=c1[p],p-=lowbit(p);
    	return ans;	
    }
    long long askc2(int p){
    	long long ans=0;
    	while(p) ans+=c2[p],p-=lowbit(p);
    	return ans;	
    }
    void subtask1(){
    	int l,r;long long x;
    	l=read(),r=read(),x=read();
    	addc1(l,x),addc1(r+1,-x),addc2(l,l*x),addc2(r+1,-(r+1)*x);
    }
    void subtask2(){
    	int l,r;l=read(),r=read();
    	long long ans;
    	ans=sum[r]+(r+1)*askc1(r)-askc2(r)-(sum[l-1]+l*askc1(l-1)-askc2(l-1));
    	printf("%lld
    ",ans);	
    }
    int main(){
    	n=read(),k=read();
    	for(int i=1;i<=n;i++) a[i]=read(),sum[i]=sum[i-1]+a[i];
    	while(k--){
    		int a;a=read();	
    		if(a==1) subtask1();
    		else subtask2();
    	}
    	return 0;
    }
    

    6 线段树1[区间gcd]

    problem

    给定序列,求指定区间内所有数的gcd。

    solution

    把线段树求和的求和回溯改成gcd。没有太大的区别。很好的板子应用。

    thoughts

    10pts:p<<1写成了p<<2
    100pts:正解。

    code

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    #include <queue>
    using namespace std;
    int read(){
    	int a=0,op=1;char c=getchar();
    	while(c>'9'||c<'0') {if(c=='-') op=-1;c=getchar();}
    	while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
    	return a*op;
    }
    const int maxn=2e5+10;
    int a[maxn<<2],tree[maxn<<2],n,m;
    int gcd(int x,int y){
    	return y==0?x:gcd(y,x%y);
    }
    void buildtree(int p,int l,int r){
    	if(l==r){tree[p]=a[l];return ;}
    	int mid=l+r>>1;
    	buildtree(p<<1,l,mid);buildtree(p<<1|1,mid+1,r);
    	tree[p]=gcd(tree[p<<1],tree[p<<1|1]);
    	return ;
    }
    int asktree(int p,int l,int r,int askl,int askr){
    	if(l==askl&&r==askr) return tree[p];
    	int mid=l+r>>1;
    	if(askl>mid) return asktree(p<<1|1,mid+1,r,askl,askr);
    	if(askr<=mid) return asktree(p<<1,l,mid,askl,askr);
    	else return gcd(asktree(p<<1|1,mid+1,r,mid+1,askr),asktree(p<<1,l,mid,askl,mid));
    }
    
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	buildtree(1,1,n);
    	int v,b;
    	while(m--){
    		v=read(),b=read();
    		printf("%d
    ",asktree(1,1,n,v,b));
    	}
    	return 0;
    }
    

    7 区间(sin)

    problem

    序列支持区间修改,所有的值加上k,区间查询(sumlimits_{i=l}^rsin(a_i))

    solution

    维护是基于

    [sin(x+y)=sin xcos y+sin ycos x ]

    [cos(x+y)=cos xcos y-sin xsin y ]

    然后就非常好做了,我们同时维护区间 (sin)和跟区间(cos)和,上传信息可以直接相加,再维护一个加法标记,用上面的和角公式可以做到 (Theta(1))下传标记。
    复杂度(Theta(mlog n))

    thoughts

    0pts:主函数里的(operatorname{query}(l,n,1,n,1,k))(l)写成了(1)

    code

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    #include <queue>
    using namespace std;
    int read(){
    	int a=0,op=1;char c=getchar();
    	while(c>'9'||c<'0') {if(c=='-') op=-1;c=getchar();}
    	while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
    	return a*op;
    }
    #define mid (l+r>>1)
    int n,q;
    const int maxn=2e5+5;
    int a[maxn];
    double sink,cosk;
    struct Segment_Tree{
    	double sine[maxn<<2],cosi[maxn<<2];
    	long long tag[maxn<<2];
    	inline void pushup(int u){
    		sine[u]=sine[u<<1]+sine[u<<1|1];
    		cosi[u]=cosi[u<<1]+cosi[u<<1|1];
    	}
    	inline void update(int u,double sinx,double cosx){
    		double sina=sine[u],cosa=cosi[u];
    		sine[u]=sina*cosx+cosa*sinx;
    		cosi[u]=cosa*cosx-sina*sinx;	
    	}
    	inline void pushdown(int u){
    		if(!tag[u]) return ;
    		double sinx=sin(tag[u]),cosx=cos(tag[u]);
    		update(u<<1,sinx,cosx);update(u<<1|1,sinx,cosx);
    		tag[u<<1]+=tag[u],tag[u<<1|1]+=tag[u];
    		tag[u]=0;	
    	}
    	void build(int l,int r,int u){
    		if(l==r){sine[u]=sin(a[l]),cosi[u]=cos(a[l]);return ;}
    		build(l,mid,u<<1),build(mid+1,r,u<<1|1);
    		pushup(u);	
    	}
    	void modify(int nl,int nr,int l,int r,int u,int k){
    		if(nl<=l&&r<=nr){
    			update(u,sink,cosk);tag[u]+=k;return ;	
    		}
    		pushdown(u);
    		if(nl<=mid) modify(nl,nr,l,mid,u<<1,k);
    		if(nr>mid) modify(nl,nr,mid+1,r,u<<1|1,k);
    		pushup(u);
    	}
    	double query(int nl,int nr,int l,int r,int u){
    		if(nl<=l&&r<=nr) return sine[u];
    		double res=0;
    		pushdown(u);
    		if(nl<=mid)res+=query(nl,nr,l,mid,u<<1);
    		if(nr>mid) res+=query(nl,nr,mid+1,r,u<<1|1);
    		return res;	
    	}
    }T;
    int main(){
    	int op,l,r,k;
    	n=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	T.build(1,n,1);
    	q=read();
    	while(q--){
    		op=read(),l=read(),r=read();
    		if(op==1){
    			k=read();sink=sin(k),cosk=cos(k);
    			T.modify(l,r,1,n,1,k);
    		}
    		else printf("%.1lf
    ",T.query(l,r,1,n,1));
    	}
    	return 0; 
    } 
    

    8 线段树

    problem

    区间修改,区间查询。

    solution

    lazy标记。真没啥可写的嘿嘿嘿。

    code

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1e6+5;
    #define int long long
    int tree[maxn<<2],a[maxn],lazy[maxn<<2];
    int n,m;
    
    int read(){
    	int a=0,op=1;char c;c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')op=-1;c=getchar();}
    	while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
    	return a*op;	
    }
    void build(int p,int l,int r){
    	if(l==r){tree[p]=a[l];return ;}
    	int mid=l+r>>1;
    	build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    	tree[p]=tree[p<<1]+tree[p<<1|1];
    }
    void pushdown(int p,int l,int r){
    	int mid=l+r>>1;
    	tree[p<<1]+=(mid-l+1)*lazy[p];
    	lazy[p<<1]+=lazy[p];
    	tree[p<<1|1]+=(r-mid)*lazy[p];
    	lazy[p<<1|1]+=lazy[p];
    	lazy[p]=0;
    }
    void update(int p,int l,int r,int ll,int rr,int x){
    	if(l==ll&&r==rr){tree[p]+=x*(r-l+1);lazy[p]+=x;return ;}
    	pushdown(p,l,r);
    	int mid=l+r>>1;
    	if(ll>mid) update(p<<1|1,mid+1,r,ll,rr,x);
    	else if(mid>=rr) update(p<<1,l,mid,ll,rr,x);
    	else update(p<<1,l,mid,ll,mid,x),update(p<<1|1,mid+1,r,mid+1,rr,x);
    	tree[p]=tree[p<<1]+tree[p<<1|1];
    }
    int query(int p,int l,int r,int askl,int askr){
    	int mid=l+r>>1;
    	if(l==askl&&r==askr) return tree[p];
    	if(lazy[p]!=0) pushdown(p,l,r);	
    	if(mid>=askr) return query(p<<1,l,mid,askl,askr);
    	else if(mid<askl) return query(p<<1|1,mid+1,r,askl,askr);
    	else return query(p<<1,l,mid,askl,mid)+query(p<<1|1,mid+1,r,mid+1,askr); 
    }
    int d,f,g,h;
    signed main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	build(1,1,n);
    	for(int i=1;i<=m;i++){
    		d=read();
    		if(d==1) f=read(),g=read(),h=read(),update(1,1,n,f,g,h);
    		else f=read(),g=read(),printf("%lld
    ",query(1,1,n,f,g));
    	}
    	return 0;
    }
    

    9 线段树[AHOI2008]

    problem

    区间乘法,区间加法,区间求和并取模。

    solution

    两个lazy标记,一个加一个乘,乘法在加法之前,pushdown是关键。

    code

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1e6+5;
    #define int long long
    int tree[maxn<<2],a[maxn],lazy1[maxn],lazy2[maxn];
    struct node{
    	int add,mul;
    }lazy[maxn<<2];
    int n,m,mod;
    //void pushup(int p){tree[p]=(tree[p<<1]%mod+tree[p<<1|1]%mod)%mod;}
    void pushup(int x){
      (tree[x]=tree[x<<1]+tree[x<<1|1])%=mod;
    }
    int read(){
    	int a=0,op=1;char c;c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')op=-1;c=getchar();}
    	while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
    	return a*op;	
    }
    void build(int p,int l,int r){
    	lazy1[p]=0,lazy2[p]=1;
    	if(l==r){tree[p]=a[l];return ;}
    	int mid=l+r>>1;
    	build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    	pushup(p);	
    }
    void tag(int p,int l,int r,int k1,int k2){
    	lazy1[p]=(lazy1[p]*k2+k1)%mod;
    	lazy2[p]=(lazy2[p]*k2)%mod;
    	tree[p]=(tree[p]*k2+k1*(r-l+1))%mod;	
    }
    void pushdown(int p,int l,int r){
    	int mid=l+r>>1;
    	tag(p<<1,l,mid,lazy1[p],lazy2[p]);
    	tag(p<<1|1,mid+1,r,lazy1[p],lazy2[p]);
    	lazy1[p]=0,lazy2[p]=1;	
    }
    void modify1(int p,int l,int r,int nl,int nr,int k){
    	if(nl<=l&&r<=nr) {tag(p,l,r,0,k);return ;}
    	int mid=l+r>>1;
    	pushdown(p,l,r);
    	if(nl<=mid) modify1(p<<1,l,mid,nl,nr,k);
    	if(nr>mid) modify1(p<<1|1,mid+1,r,nl,nr,k);
    	pushup(p);
    }
    void modify2(int p,int l,int r,int nl,int nr,int k){
    	if(nl<=l&&r<=nr) {tag(p,l,r,k,1);return ;}
    	int mid=l+r>>1;
    	pushdown(p,l,r);
    	if(nl<=mid) modify2(p<<1,l,mid,nl,nr,k);
    	if(nr>mid) modify2(p<<1|1,mid+1,r,nl,nr,k);
    	pushup(p);	
    }int x,y,k;
    int query(int p,int l,int r,int nl,int nr){
    	int res=0;
    	if (nl<=l&&r<=nr) return tree[p];
    	int mid=l+r>>1;
    	pushdown(p,l,r);
    	if(nl<=mid) res+=query(p<<1,l,mid,nl,nr);
    	if(nr>mid) res+=query(p<<1|1,mid+1,r,nl,nr);
    	return res%mod;	
    }
    void d(){
    	printf("%lld %lld %lld:",x,y,k);
    	for(int i=1;i<=n;i++) printf("%lld ",query(1,1,n,i,i));
    	printf("
    ");	
    }
    signed main(){
    	n=read(),mod=read();
    	//printf("%lld
    ",mod);
    	for(int i=1;i<=n;i++) a[i]=read();
    	m=read();
    	build(1,1,n);
    	for(int i=1;i<=m;i++) {
    		int op=read();
    		if(op==1) x=read(),y=read(),k=read(),modify1(1,1,n,x,y,k);
    		if(op==2) x=read(),y=read(),k=read(),modify2(1,1,n,x,y,k);
    		if(op==3) x=read(),y=read(),printf("%lld
    ",(query(1,1,n,x,y)%mod));
    	}
    	return 0;	
    }
    

    10 线段树

    problem

    区间修改,区间平均数,区间方差。

    solution

    code

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1e5+10;
    int read(){
    	int a=0,op=1;char c;c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')op=-1;c=getchar();}
    	while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
    	return a*op;	
    }
    int n,m;
    double a[maxn],tree1[maxn<<2],tree2[maxn<<2];
    double lazy[maxn<<2];
    void pushup(int p){
    	tree1[p]=tree1[p<<1]+tree1[p<<1|1];
    	tree2[p]=tree2[p<<1]+tree2[p<<1|1];
    }
    void build(int p,int l,int r){
    	if(l==r) {tree1[p]=a[l],tree2[p]=a[l]*a[l];return ;}
    	int mid=l+r>>1;
    	build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    	pushup(p);
    }
    void tag(int p,int l,int r,double k){
    	lazy[p]+=k;
    	tree2[p]+=(r-l+1)*k*k+tree1[p]*2*k;
    	tree1[p]+=(r-l+1)*k;
    }
    void pushdown(int p,int l,int r){
    	int mid=l+r>>1;
    	tag(p<<1,l,mid,lazy[p]);
    	tag(p<<1|1,mid+1,r,lazy[p]);
    	lazy[p]=0;
    }
    void modify(int p,int l,int r,int nl,int nr,double k){
    	if(nl<=l&&r<=nr){tag(p,l,r,k);return ;}
    	int mid=l+r>>1;
    	pushdown(p,l,r);
    	if(nl<=mid) modify(p<<1,l,mid,nl,nr,k);
    	if(nr>mid) modify(p<<1|1,mid+1,r,nl,nr,k);
    	pushup(p);
    }
    double query1(int p,int l,int r,int nl,int nr){
    	double res=0;
    	if(nl<=l&&r<=nr) return tree1[p];
    	int mid=l+r>>1;
    	pushdown(p,l,r);
    	if(nl<=mid) res+=query1(p<<1,l,mid,nl,nr);
    	if(nr>mid) res+=query1(p<<1|1,mid+1,r,nl,nr);
    	return res;
    }
    double query2(int p,int l,int r,int nl,int nr){
    	double res=0;
    	if(nl<=l&&r<=nr) return tree2[p];
    	int mid=l+r>>1;
    	pushdown(p,l,r);
    	if(nl<=mid) res+=query2(p<<1,l,mid,nl,nr);
    	if(nr>mid) res+=query2(p<<1|1,mid+1,r,nl,nr);
    	return res;
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
    	build(1,1,n);
    	for(int i=1;i<=m;i++){
    		int op,x,y;double k;
    		op=read();
    		if(op==1){
    			x=read(),y=read();
    			scanf("%lf",&k);
    			modify(1,1,n,x,y,k);
    		}
    		if(op==2){
    			x=read(),y=read();
    			double tmp=query1(1,1,n,x,y);
    			double ans=tmp/((y-x+1)*1.0);
    			printf("%.4lf
    ",ans);
    		}
    		if(op==3){
    			x=read(),y=read();
    			double tmp1=query1(1,1,n,x,y),tmp2=query2(1,1,n,x,y);
    			double ans1=tmp2/((y-x+1)*1.0),ans2=tmp1/((y-x+1)*1.0);
    			ans2=ans2*ans2;
    			double ans=ans1-ans2;
    			printf("%.4lf
    ",ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    vi
    实用基本程序
    常用排序算法总结
    Windows 远程在Linux下 发布tomcat web程序
    Java 8 函数式编程
    Scanner
    Mysql【JDBC】
    RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 1 #805
    KeyError: 'module_list.85.Conv2d.weight' #657
    C语言 BIT
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/20201019day39-002.html
Copyright © 2011-2022 走看看