• P4145 上帝造题的七分钟 2 / 花神游历各国(线段树)


    区间开平方直接上暴力即可。

    因为一个数开几次就到1了。

    维护一个区间最大值,当该区间最大值是1的时候直接return。

    复杂度O(nlognlogn)?

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    int n,m;
    long long a[maxn],c[maxn<<2],mx[maxn<<2];
    void build (int i,int l,int r) {
    	if (l==r) {
    		c[i]=mx[i]=a[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(i<<1,l,mid);
    	build(i<<1|1,mid+1,r);
    	c[i]=c[i<<1]+c[i<<1|1];
    	mx[i]=max(mx[i<<1],mx[i<<1|1]);
    } 
    void up (int i,int l,int r,int L,int R) {
    	if (mx[i]==1) return;
    	if (l==r) {
    		c[i]=sqrt(c[i]);
    		mx[i]=sqrt(mx[i]);
    		return;
    	}
    	int mid=(l+r)>>1;
    	if (L<=mid) up(i<<1,l,mid,L,R);
    	if (R>mid) up(i<<1|1,mid+1,r,L,R);
    	c[i]=c[i<<1]+c[i<<1|1];
    	mx[i]=max(mx[i<<1],mx[i<<1|1]);
    } 
    long long query (int i,int l,int r,int L,int R) {
    	if (l>=L&&r<=R) return c[i];
    	int mid=(l+r)>>1;
    	long long ans=0;
    	if (L<=mid) ans+=query(i<<1,l,mid,L,R);
    	if (R>mid) ans+=query(i<<1|1,mid+1,r,L,R);
    	return ans;
    }
    int main () {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%lld",a+i);
    	build(1,1,n);
    	int q;
    	scanf("%d",&q);
    	while (q--) {
    		int k,l,r;
    		scanf("%d%d%d",&k,&l,&r);
    		if (l>r) swap(l,r);
    		if (k==0) {
    			up(1,1,n,l,r);
    		}
    		else {
    			printf("%lld
    ",query(1,1,n,l,r));
    		}
    	}
    }
  • 相关阅读:
    BZOJ-1034-[ZJOI2008]泡泡堂BNB(贪心)
    BZOJ-2456-mode(思维题)
    POJ-2528-Mayor's posters(线段树+离散化)
    POJ-2352-Stars(树状数组)
    HDU-2688-Rotate(树状数组)
    POJ-1195-Mobile phones(二维树状数组)
    YYHS-NOIP2017Training0921-逆光
    YYHS-鏖战字符串(斜率优化)
    左偏树
    2-sat模板
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15041453.html
Copyright © 2020-2023  润新知