• 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('
    ');
    	}
    }
    
  • 相关阅读:
    08:特殊日历计算
    07:玛雅历
    Vigenère密码
    openjudge 螺旋加密
    C#遍历指定文件夹中的所有文件和子文件夹
    确定两串乱序同构
    方阵原地顺时针旋转90度
    05:统计单词数【NOIP2011复赛普及组第二题】
    牛客网一道趣味题
    二分查找的平均查找长度详解【转】
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14791623.html
Copyright © 2020-2023  润新知