您的位置:首页 > 其它

bzoj3211: 花神游历各国

2017-03-29 17:59 260 查看

链接

  http://www.lydsy.com/JudgeOnline/problem.php?id=3211

题解

  容易发现,109开6平方根就变成1了,所以可以每个线段树开一个w数组,wi表示这个区间整体开i次根号的和是多少,tag表示这个区间被整体开根了多少次。

  更新的时候直接枚举左右儿子的wi然后加起来就好了,下放标记的时候让wi整体滚动就行了。

  这道题加了数据之后卡常数,它本意可能是想卡分块…但是线段树常数大的话也可能卡掉(我就被卡掉了)。在下放标记和用儿子更新自己的时候,如果发现w1=w2,那说明所有数都已经开根到极限了,这时候可以直接退出。

  然后就过了。

代码

//线段树
#include <cstdio>
#include <algorithm>
#include <cmath>
#define maxn 100010
#define ll long long
using namespace std;
ll N, M, ndtot, a[maxn], building=1;
struct segtree
{
ll l, r, w[7], tag;
segtree *ch[2], *f;
}pool[maxn*4], *root;
inline ll read(ll x=0)
{
char c=getchar();
while(c<48 or c>57)c=getchar();
while(c>=48 and c<=57)x=(x<<1)+(x<<3)+c-48,c=getchar();
return x;
}
inline void pushdown(segtree *p)
{
if(p->tag)
{
if(p->w[1]==p->w[2]){p->tag=0;return;}
ll i;
for(i=1;i<=6;i++)p->w[i]=p->w[min(6ll,i+p->tag)];
if(p->ch[0])p->ch[0]->tag+=p->tag, p->ch[1]->tag+=p->tag;
p->tag=0;
}
}
inline void pushup(segtree *p)
{
if(p->l==p->r)return;
ll i;
pushdown(p->ch[0]), pushdown(p->ch[1]);
if(!building and p->w[1]==p->w[2])return;
for(i=1;i<=6;i++)p->w[i]=p->ch[0]->w[i]+p->ch[1]->w[i];
}
void segtag(segtree *p, ll l, ll r)
{
pushdown(p);
ll mid=(p->l+p->r)>>1;
if(l<=p->l and r>=p->r){p->tag++;return;}
if(l<=mid)segtag(p->ch[0],l,r);
if(r>mid)segtag(p->ch[1],l,r);
pushup(p);
}
ll segsum(segtree *p, ll l, ll r)
{
pushdown(p);
ll mid=(p->l+p->r)>>1, ans=0;
if(l<=p->l and r>=p->r)return p->w[1];
if(l<=mid)ans+=segsum(p->ch[0],l,r);
if(r>mid)ans+=segsum(p->ch[1],l,r);
return ans;
}
void build(segtree *p, ll l, ll r)
{
ll mid=(l+r)>>1, i;
p->l=l, p->r=r;
if(l==r)
{
p->w[1]=a[l];
for(i=2;i<=6;i++)p->w[i]=sqrt(p->w[i-1]);
return;
}
build(p->ch[0]=pool+ ++ndtot,l,mid);
build(p->ch[1]=pool+ ++ndtot,mid+1,r);
pushup(p);
}
int main()
{
ll x, l, r, i;
N=read();
for(i=1;i<=N;i++)a[i]=read();
build(root=pool+ ++ndtot,1,N);
building=0;
M=read();
for(i=1;i<=M;i++)
{
x=read(), l=read(), r=read();
if(x==1)printf("%lld\n",segsum(root,l,r));
if(x==2)segtag(root,l,r);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: