洛谷 SP2713 GSS4

题目链接

区间每个数开方,区间和查询

显然区间开方不具有加法性,线段树不可直接维护

我们于是思考其他做法优化

首先是1/0的开方不影响本身

统计区间小于等于1的数,如果刚好和区间长度一致,则区间操作可省略

等价于区间最大值小于等于1

[code]


#include <bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define ls (nod<<1)
#define rs (nod<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define int long long

long long read(){
    long long x=0,flag=1; char c;
    for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') flag=-1;
    for(;isdigit(c);c=getchar()) x=((x+(x<<2))<<1)+(c^48);
    return x*flag;
}

const int N=1e5+10;

int n,m;

struct Node{
	int l,r;
    long long sum,mx;
}t[N<<2];

Node Union(Node x,Node y){
    Node z;
    z.l=x.l; z.r=y.r;
    z.sum=x.sum+y.sum;
    z.mx=max(x.mx,y.mx);
    return z;
}

void pushup(int nod){
    if(t[nod].l==t[nod].r) return ;
    t[nod]=Union(t[ls],t[rs]);
}

void build(int nod,int l,int r){
    t[nod].l=l,t[nod].r=r;
    
    if(l==r){
	    t[nod].sum=t[nod].mx=read();
	    return ;
	}
	
	build(lson); build(rson);
	pushup(nod);
}

void update(int nod,int l,int r,int ll,int rr){
	if(l>rr||r<ll) return ;
	if(t[nod].mx==1) return ;
	if(l==r) { t[nod].sum=t[nod].mx=(long long)sqrt(t[nod].sum); return ; }
	update(lson,ll,rr); update(rson,ll,rr);
	pushup(nod);
}

long long query(int nod,int l,int r,int ll,int rr){
    if(l>rr||r<ll) return 0;
    if(ll<=l&&r<=rr) return t[nod].sum;
    return query(lson,ll,rr)+query(rson,ll,rr);
}

signed main() {
	int T=0;
    while(scanf("%lld",&n)!=EOF){
	    ++T; printf("Case #%lld:\n",T);
	    
		build(1,1,n);
	    m=read();
	    for(int i=1;i<=m;i++){
		    int opt=read();
		    int l=read(),r=read();
		    if(l>r) swap(l,r);
		    if(!opt) update(1,1,n,l,r);
		    else printf("%lld\n",query(1,1,n,l,r));
		}
		printf("\n");
	}
	return 0;
}


posted @ 2020-01-17 19:37  zhuzihan  阅读(106)  评论(0编辑  收藏  举报