hdu 5828 线段树

来源:互联网 发布:套利定价知乎 编辑:程序博客网 时间:2024/06/07 03:01



链接:戳这里


Rikka with Sequence

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has an array A with n numbers. Then he makes m operations on it. 

There are three type of operations:

1 l r x : For each i in [l,r], change A[i] to A[i]+x
2 l r : For each i in [l,r], change A[i] to ⌊A√[i]⌋
3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]

It is too difficult for Rikka. Can you help her?
 
Input
The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.

For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.

It is guaranteed that 1<=A[i],x<=100000.
 
Output
For each operation of type 3, print a lines contains one number -- the answer of the query.
 
Sample Input
1
5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5
 
Sample Output
5
6


题意:

三个操作:

1  x y v 区间[x,y]值增加v

2 x y 区间[x,y]的值开根号

3 x y 查询区间[x,y]的和


思路:

额 由于开根号这个操作会使得数尽可能的趋于一致 ,然后直接暴力就可以,记录一下区间的数是否一样

(听说有人手构数据让标程T


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<list>#include<stack>#include<iomanip>#include<cmath>#include<bitset>#define mst(ss,b) memset((ss),(b),sizeof(ss))///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef long double ld;#define INF (1ll<<60)-1#define Max 1e9using namespace std;const long double eps=1e-8;ll lazy[500100],sum[500100],a[100100],same[500100];void pushup(int root){    sum[root]=sum[root*2]+sum[root*2+1];    if(same[root*2]==same[root*2+1] && same[root*2])        same[root]=same[root*2];    else same[root]=0;}void build(int root,int l,int r){    same[root]=lazy[root]=0;    if(l==r){        sum[root]=a[l];        same[root]=a[l];        return ;    }    int mid=(l+r)/2;    build(root*2,l,mid);    build(root*2+1,mid+1,r);    pushup(root);}void pushdown(int root,int len){    if(same[root]){        same[root*2]=same[root*2+1]=same[root];        sum[root*2]=same[root]*1LL*(len-len/2);        sum[root*2+1]=same[root]*1LL*(len/2);        lazy[root]=0;    }    if(lazy[root]){        lazy[root*2]+=lazy[root];        lazy[root*2+1]+=lazy[root];        if(same[root*2]) same[root*2]+=lazy[root];        if(same[root*2+1]) same[root*2+1]+=lazy[root];        sum[root*2]+=1LL*(len-len/2)*lazy[root];        sum[root*2+1]+=1LL*(len/2)*lazy[root];        lazy[root]=0;    }}void update1(int root,int l,int r,int x,int y,ll v){    if(x<=l && y>=r){        sum[root]+=1LL*(r-l+1)*v;        lazy[root]+=v;        if(same[root]) same[root]+=v;        return ;    }    pushdown(root,r-l+1);    int mid=(l+r)/2;    if(y<=mid) update1(root*2,l,mid,x,y,v);    else if(x>mid) update1(root*2+1,mid+1,r,x,y,v);    else {        update1(root*2,l,mid,x,mid,v);        update1(root*2+1,mid+1,r,mid+1,y,v);    }    pushup(root);}void update2(int root,int l,int r,int x,int y){    if(x<=l && y>=r && same[root]){        same[root]=(ll)sqrt(1.0*same[root]+0.5);        sum[root]=1LL*(r-l+1)*same[root];        return ;    }    pushdown(root,r-l+1);    int mid=(l+r)/2;    if(y<=mid) update2(root*2,l,mid,x,y);    else if(x>mid) update2(root*2+1,mid+1,r,x,y);    else {        update2(root*2,l,mid,x,mid);        update2(root*2+1,mid+1,r,mid+1,y);    }    pushup(root);}ll query(int root,int l,int r,int x,int y){    if(x<=l && y>=r){        return sum[root];    }    int mid=(l+r)/2;    pushdown(root,r-l+1);    ll ans=0;    if(x<=mid) ans+=query(root*2,l,mid,x,y);    if(y>mid) ans+=query(root*2+1,mid+1,r,x,y);    return ans;}int n,m;int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        mst(sum,0);        mst(lazy,0);        mst(same,0);        for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);        build(1,1,n);        for(int i=1;i<=m;i++){            int t,x,y;            ll v;            scanf("%d",&t);            if(t==1){                scanf("%d%d%I64d",&x,&y,&v);                update1(1,1,n,x,y,v);            } else if(t==2){                scanf("%d%d",&x,&y);                update2(1,1,n,x,y);            } else {                scanf("%d%d",&x,&y);                printf("%I64d\n",query(1,1,n,x,y));            }        }    }    return 0;}


0 0