【BZOJ 3211&3038】 花神遊歷各國 & 上帝造題的七分鐘2

【題目鏈接】

          【BZOJ 3211】 點擊打開鏈接

          【BZOJ 3038】 點擊打開鏈接

【算法】

            線段樹

            開根操作直接開到葉子節點,注意當區間中所有數都是0或1時,不需要開根

【代碼】

           

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010

int i,n,m,opt,l,r;
long long a[MAXN];

struct SegmentTree
{
		struct Node
		{
				int l,r;
				long long sum;
				bool flag;
		} Tree[MAXN<<2];
		inline void update(int index)
		{
				Tree[index].sum = Tree[index<<1].sum + Tree[index<<1|1].sum;
				Tree[index].flag = Tree[index<<1].flag & Tree[index<<1|1].flag;
		}
		inline void build(int index,int l,int r)
		{
				int mid;
				Tree[index].l = l; Tree[index].r = r;
				if (l == r) 
				{
						Tree[index].sum = a[l];
						if (a[l] == 0 || a[l] == 1) Tree[index].flag = true;
						else Tree[index].flag = false;
						return;
				}
				mid = (l + r) >> 1;
				build(index<<1,l,mid);
				build(index<<1|1,mid+1,r);
				update(index);
		}
		inline void modify(int index,int l,int r)
		{
				int mid;
				if (Tree[index].flag) return;
				if (Tree[index].l == Tree[index].r) 
				{
						Tree[index].sum = (long long)sqrt(Tree[index].sum);
						if (Tree[index].sum == 0 || Tree[index].sum == 1) Tree[index].flag = true;
						return;
				}
				mid = (Tree[index].l + Tree[index].r) >> 1;
				if (mid >= r) modify(index<<1,l,r);
				else if (mid + 1 <= l) modify(index<<1|1,l,r);
				else
				{
						modify(index<<1,l,mid);
						modify(index<<1|1,mid+1,r);
				}
				update(index);
		}
		inline long long query(int index,int l,int r)
		{
				int mid;
				if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum;
				mid = (Tree[index].l + Tree[index].r) >> 1;
				if (mid >= r) return query(index<<1,l,r);
				else if (mid + 1 <= l) return query(index<<1|1,l,r);
				else return query(index<<1,l,mid) + query(index<<1|1,mid+1,r);
		}
} T;
template <typename T> inline void read(T &x)
{
    int f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
template <typename T> inline void write(T x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9) write(x/10);
    putchar(x%10+'0');
}
template <typename T> inline void writeln(T x)
{
    write(x);
    puts("");
}

int main() {
		
		read(n); 
		for (i = 1; i <= n; i++) read(a[i]);
		T.build(1,1,n);
		read(m);
		while (m--)
		{
				read(opt);
				if (opt == 1)
				{
						read(l); read(r);
						writeln(T.query(1,l,r));
				} else
				{
						read(l); read(r);
						T.modify(1,l,r);
				}
		}
		return 0;
	
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章