您的位置:首页 > 其它

BZOJ 3038: 上帝造题的七分钟2

2017-06-03 17:20 260 查看
二次联通门 : BZOJ 3038: 上帝造题的七分钟2

/*
BZOJ 3038: 上帝造题的七分钟2

线段树维护区间和

对于开方操作
思考一下, 若其为1或0
则无论其怎样开方值, 都不会再改变

那么打个标记即可,
若当前节点的左儿子和右儿子都小于等于1, 那么就没有再进行下去的必要了

标记依次上传即可
*/
#include <cstdio>
#include <cmath>

void read (long long &now)
{
now = 0;
register char word = getchar ();
while (word < '0' || word > '9')
word = getchar ();
while (word >= '0' && word <= '9')
{
now = now * 10 + word - '0';
word = getchar ();
}
}

inline long long min (long long a, long long b)
{
return a < b ? a : b;
}

inline long long max (long long a, long long b)
{
return a > b ? a : b;
}

struct Segment_Tree_Date
{
Segment_Tree_Date *Left, *Right;

long long l, r;

long long Mid;
long long key;
bool Flandre;

Segment_Tree_Date ()
{
Left = NULL;
Right = NULL;
key = 0;
Flandre = false;
}
};

Segment_Tree_Date *Root;

class Segment_Tree_Type
{
public :

void Build (Segment_Tree_Date *&now, long long l, long long r)
{
now = new Segment_Tree_Date ;
now->l = l;
now->r = r;
if (l == r)
{
read (now->key);
if (now->key <= 1)
now->Flandre = true;
return ;
}
now->Mid = l + r >> 1;
Build (now->Left, l, now->Mid);
Build (now->Right, now->Mid + 1, r);
now->key = now->Left->key + now->Right->key;
now->Flandre = now->Left->Flandre & now->Right->Flandre;
}

void Change_Section (Segment_Tree_Date *&now, long long l, long long r)
{
if (now->l == now->r)
{
now->key = (long long)sqrt (now->key);
if (now->key <= 1)
now->Flandre = true;
return ;
}
if (now->Flandre)
return ;
if (l <= now->Mid)
Change_Section (now->Left, l, min (now->Mid, r));
if (r > now->Mid)
Change_Section (now->Right, max (now->Mid + 1, l), r);
now->key = now->Left->key + now->Right->key;
now->Flandre = now->Left->Flandre & now->Right->Flandre;
}

long long Query_Section (Segment_Tree_Date *&now, long long l, long long r)
{
if (l <= now->l && now->r <= r)
return now->key;
long long res = 0;
if (l <= now->Mid)
res += Query_Section (now->Left, l, min (now->Mid, r));
if (r > now->Mid)
res += Query_Section (now->Right, max (now->Mid + 1, l), r);
return res;
}
};

Segment_Tree_Type Tree;

long long N;

int main (int argc, char *argv[])
{
read (N);
Tree.Build (Root, 1, N);
long long x, y, type;
for (read (N); N--; )
{
read (type);
read (x);
read (y);
if (type)
printf ("%lld\n", Tree.Query_Section (Root, min (x, y), max (x, y)));
else
Tree.Change_Section (Root, min (x, y), max (x, y));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: