zoukankan      html  css  js  c++  java
  • HDU 4027

    这道题最初思路是线段树维护每段区间被开平方的次数,然后最终query的时候取个循环,但是这样时间复杂度还是受不住

    这道题的非线性导致了不小的麻烦,死板的想要依然遵循线段树延迟修改最后无路可走,所以,这道题的线段树很特殊,每次更新,都更新到最终的叶子节点为止(这也是看题解才收获的,还是需要训练量培养思路生成)

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <deque>
    using namespace std;
    
    const int maxn= 1e5+5;
    typedef unsigned long long LL;
    
    struct Seg
    {
    	int l, r;
    	LL sum;
    }segTree[maxn<<2];
    int n, m, op, x, y;
    
    void Build(int x, int l, int r)
    {
    	segTree[x].l= l;
    	segTree[x].r= r;
    	if (l== r){
    		scanf("%llu", &segTree[x].sum);
    		return;
    	}
    	int mid= (l+r)>>1;
    	Build(x<<1, l, mid);
    	Build(x<<1|1, mid+1, r);
    	segTree[x].sum= segTree[x<<1].sum+segTree[x<<1|1].sum;
    }
    void Update(int x, int l, int r)
    {
    	if (l> r){
    		return;
    	}
    	if (segTree[x].sum== (LL)(segTree[x].r-segTree[x].l+1)){
    		return;
    	}
    	if (segTree[x].l== segTree[x].r){
    		segTree[x].sum= sqrt(1.0*segTree[x].sum);
    		return;
    	}
    	int mid= (segTree[x].l+segTree[x].r)>>1;
    	if (mid>= r){
    		Update(x<<1, l, r);
    	}
    	else if (mid< l){
    		Update(x<<1|1, l, r);
    	}
    	else{
    		Update(x<<1, l, mid);
    		Update(x<<1|1, mid+1, r);
    	}
    	segTree[x].sum= segTree[x<<1].sum+segTree[x<<1|1].sum;
    }
    LL Query(int x, int l, int r)
    {
    	if (l> r){
    		return 0;
    	}
    	if (l== segTree[x].l && r== segTree[x].r){
    		return segTree[x].sum;
    	}
    	int mid= (segTree[x].l+segTree[x].r)>>1;
    	if (mid>= r){
    		return Query(x<<1, l, r);
    	}
    	else if (mid< l){
    		return Query(x<<1|1, l, r);
    	}
    	else{
    		return Query(x<<1, l, mid)+Query(x<<1|1, mid+1, r);
    	}
    }
    int main()
    {
    	int kase= 0;
    	while (~scanf("%d", &n)){
    		Build(1, 1, n);
    		scanf("%d", &m);
    		printf("Case #%d:
    ", ++kase);
    		while (m--){
    			scanf("%d %d %d", &op, &x, &y);
    			if (x> y){
    				swap(x, y);
    			}
    			if (op){
    				printf("%llu
    ", Query(1, x, y));
    			}
    			else{
    				Update(1, x, y);
    			}
    		}
    		putchar('
    ');
    	}
    }
    
  • 相关阅读:
    ThinkPHP安全规范指引
    正则表达式:不能包含某些特殊字符串
    头晕是因为虚 ( ̄^ ̄゜)
    vs code中文扩展包
    table-cell width:1% 深入理解
    C#使用NPOI操作Excel
    C#利用LumenWorks.Framework.IO.Csv读取CSV文件
    发送邮件代码
    .net 集合详解
    EF Code First:数据更新最佳实践
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14791623.html
Copyright © 2011-2022 走看看