uoj #228. 基础数据结构练习题 线段树

#228. 基础数据结构练习题

 统计

sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧。

在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手。于是她的好朋友九条可怜酱给她出了一道题。

给出一个长度为 nn 的数列 AA,接下来有 mm 次操作,操作有三种:

  1. 对于所有的 i[l,r]i∈[l,r],将 AiAi 变成 Ai+xAi+x。
  2. 对于所有的 i[l,r]i∈[l,r],将 AiAi 变成 Ai−−√⌊Ai⌋。
  3. 对于所有的 i[l,r]i∈[l,r],询问 AiAi 的和。

作为一个不怎么熟练的初学者,sylvia 想了好久都没做出来。而可怜酱又外出旅游去了,一时间联系不上。于是她决定向你寻求帮助:你能帮她解决这个问题吗。

输入格式

第一行两个数:n,mn,m。

接下来一行 nn 个数 AiAi。

接下来 mm 行中,第 ii 行第一个数 titi 表示操作类型:

若 ti=1ti=1,则接下来三个整数 li,ri,xili,ri,xi,表示操作一。

若 ti=2ti=2,则接下来三个整数 li,rili,ri,表示操作二。

若 ti=3ti=3,则接下来三个整数 li,rili,ri,表示操作三。

输出格式

对于每个询问操作,输出一行表示答案。

样例一

input

5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5

output

5
6

 inline大法好;

 

读入优化大法好。

判断区间最小值跟最大值相差1或者0即可;

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-7
#define bug(x)  cout<<"bug"<<x<<endl;
const int N=1e5+10,M=1e6+10,inf=2147483647;
const ll INF=1e18+10,mod=2147493647;
inline ll scan()
{
    ll res = 0 , ch ;
    while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
    {
        if( ch == EOF )  return 1LL << 30 ;
    }
    res = ch - '0' ;
    while( ( ch = getchar() ) >= '0' && ch <= '9' )
        res = res * 10 + ( ch - '0' ) ;
    return res ;
}
///   数组大小
int n;
ll sum[N<<2],minn[N<<2],maxx[N<<2],lazy[N<<2],cov[N<<2];
inline void pushup(int pos)
{
    minn[pos]=min(minn[pos<<1],minn[pos<<1|1]);
    maxx[pos]=max(maxx[pos<<1|1],maxx[pos<<1]);
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
inline void pushdown(int pos,int l,int r)
{
    if(cov[pos])
    {
        int mid=(l+r)>>1;
        cov[pos<<1]=cov[pos];
        cov[pos<<1|1]=cov[pos];
        maxx[pos<<1]=cov[pos];
        maxx[pos<<1|1]=cov[pos];
        minn[pos<<1]=cov[pos];
        minn[pos<<1|1]=cov[pos];
        sum[pos<<1]=cov[pos]*(mid-l+1);
        sum[pos<<1|1]=cov[pos]*(r-mid);
        lazy[pos<<1]=0;
        lazy[pos<<1|1]=0;
        cov[pos]=0;
    }
    if(lazy[pos])
    {
        int mid=(l+r)>>1;
        lazy[pos<<1]+=lazy[pos];
        lazy[pos<<1|1]+=lazy[pos];
        maxx[pos<<1]+=lazy[pos];
        maxx[pos<<1|1]+=lazy[pos];
        minn[pos<<1]+=lazy[pos];
        minn[pos<<1|1]+=lazy[pos];
        sum[pos<<1]+=lazy[pos]*(mid-l+1);
        sum[pos<<1|1]+=lazy[pos]*(r-mid);
        lazy[pos]=0;
    }
}
inline void build(int l,int r,int pos)
{
    lazy[pos]=0;
    cov[pos]=0;
    if(l==r)
    {
        sum[pos]=scan();
        minn[pos]=maxx[pos]=sum[pos];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,pos<<1);
    build(mid+1,r,pos<<1|1);
    pushup(pos);
}
inline void update(int L,int R,ll c,int l,int r,int pos)
{
    if(L<=l&&r<=R)
    {
        lazy[pos]+=c;
        minn[pos]+=c;
        maxx[pos]+=c;
        sum[pos]+=c*(r-l+1);
        return;
    }
    pushdown(pos,l,r);
    int mid=(l+r)>>1;
    if(L<=mid)update(L,R,c,l,mid,pos<<1);
    if(R>mid)update(L,R,c,mid+1,r,pos<<1|1);
    pushup(pos);
}
inline void update1(int L,int R,ll c,int l,int r,int pos)
{
    if(L<=l&&r<=R)
    {
        cov[pos]=c;
        minn[pos]=c;
        maxx[pos]=c;
        sum[pos]=c*(r-l+1);
        lazy[pos]=0;
        return;
    }
    pushdown(pos,l,r);
    int mid=(l+r)>>1;
    if(L<=mid)update1(L,R,c,l,mid,pos<<1);
    if(R>mid)update1(L,R,c,mid+1,r,pos<<1|1);
    pushup(pos);
}
inline void update2(int L,int R,int l,int r,int pos)
{
    if(l==L&&R==r&&maxx[pos]==minn[pos])
    {
        ll x=(ll)floor(sqrt(maxx[pos]));
        update1(L,R,x,1,n,1);
        return;
    }
    if(l==L&&R==r&&maxx[pos]==minn[pos]+1)
    {
        ll x=(ll)floor(sqrt(maxx[pos]));
        ll y=(ll)floor(sqrt(minn[pos]));
        if(x==y)update1(L,R,x,1,n,1);
        else update(L,R,x-maxx[pos],1,n,1);
        return;
    }
    pushdown(pos,l,r);
    int mid=(l+r)>>1;
    if(R<=mid)update2(L,R,l,mid,pos<<1);
    else if(L>mid)update2(L,R,mid+1,r,pos<<1|1);
    else
    {
        update2(L,mid,l,mid,pos<<1);
        update2(mid+1,R,mid+1,r,pos<<1|1);
    }
    pushup(pos);
}
inline ll query(int L,int R,int l,int r,int pos)
{
    if(L<=l&&r<=R)return sum[pos];
    pushdown(pos,l,r);
    int mid=(l+r)>>1;
    ll ans=0;
    if(L<=mid)ans+=query(L,R,l,mid,pos<<1);
    if(R>mid)ans+=query(L,R,mid+1,r,pos<<1|1);
    return ans;
}
int main()
{
    int m;
    n=scan();
    m=scan();
    build(1,n,1);
    while(m--)
    {
        int t,l,r;
        t=scan();
        l=scan();
        r=scan();
        if(t==1)
        {
            ll x;
            x=scan();
            update(l,r,x,1,n,1);
        }
        else if(t==2) update2(l,r,1,n,1);
        else printf("%lld\n",query(l,r,1,n,1));
    }
    return 0;
}

 

posted @ 2017-04-29 15:11  jhz033  阅读(427)  评论(7编辑  收藏  举报