浏览器标题切换
浏览器标题切换end

HDU4578-Transformation-线段树的加、乘、变、次方操作

Sample Input
5 5
3 3 5 7
1 2 4 4
4 1 5 2
2 2 5 8
4 3 5 3
0 0

Sample Output

307
7489

题意:
给出n,m,表示该数有n个节点,m次操作。
接下来m次操作,op、x、y、z,
op=1时,将区间内每个元素+z
op=2时,将区间内每个元素*z
op=3时
,将区间内每个元素都变成z
op=4时,求出区间内每个元素的p次方之和输出且对mod10007取余。


数组说明:
a[i]:该区间相等元素值
book[i]: 假设该节点下面的儿子节点全部相等则标记为0,否则为1


对于op=4时的次方操作:
if(L<=l&&r<=R&&book[i]==0)
{
    ll ans=1;
    for(int k=0; k<p; k++)
        ans=(ans*a[i])%mod;
    ans=(ans*(r-l+1))%mod;
    return ans;
}

 


  1 #include<stdio.h>
  2 #include<map>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<algorithm>
  6 #include<stack>
  7 #include<cmath>
  8 #include<vector>
  9 using namespace std;
 10 typedef long long ll;
 11 const int mod=10007;
 12 const int N=1e5+20;
 13 
 14 int a[4*N];
 15 bool book[4*N];
 16 
 17 void pushdown(int i)
 18 {
 19     if(book[i<<1]||book[i<<1|1])
 20         book[i]=1;
 21     else if(a[i<<1]!=a[i<<1|1])
 22         book[i]=1;
 23     else
 24     {
 25         book[i]=0;
 26         a[i]=a[i<<1]=a[i<<1|1];//因为a[i<<1]==a[i<<1|1]
 27     }
 28 }
 29 //1 x y 1 n
 30 void update(int i,int L,int R,int l,int r,int z,int op)
 31 {
 32     if(L<=l&&r<=R&&book[i]==0)//1不相等 0相等
 33     {
 34         if(op==1)
 35             a[i]=(a[i]+z)%mod;
 36         else if(op==2)
 37             a[i]=(a[i]*z)%mod;
 38         else if(op==3)
 39             a[i]=z;
 40         return;
 41     }
 42     if(book[i]==0)
 43     {
 44         book[i<<1]=book[i<<1|1]=0;
 45         a[i<<1]=a[i<<1|1]=a[i];
 46         book[i]=1;
 47     }
 48     int mid=(l+r)>>1;
 49     if(L<=mid)
 50         update(i<<1,L,R,l,mid,z,op);
 51     if(R>mid)
 52         update(i<<1|1,L,R,mid+1,r,z,op);
 53     pushdown(i);//a[i]=a[i<<1]+a[i<<1|1];
 54 }
 55 
 56 ll query(int i,int L,int R,int l,int r,int p)
 57 {
 58     if(L<=l&&r<=R&&book[i]==0)
 59     {
 60         ll ans=1;
 61         for(int k=0;k<p;k++)
 62             ans=(ans*a[i])%mod;
 63         ans=(ans*(r-l+1))%mod;
 64         return ans;
 65     }
 66     if(book[i]==0)
 67     {
 68         book[i<<1]=book[i<<1|1]=0;
 69         a[i<<1]=a[i<<1|1]=a[i];
 70         book[i]=1;
 71     }
 72     int mid=(l+r)>>1;
 73     ll ans=0;
 74     if(L<=mid)
 75         ans+=query(i<<1,L,R,l,mid,p);
 76     if(R>mid)
 77         ans+=query(i<<1|1,L,R,mid+1,r,p);
 78     return ans%mod;
 79 
 80 }
 81 
 82 int main()
 83 {
 84     int n,m,op,L,R,z;
 85     while(cin>>n>>m)
 86     {
 87         if(n==0&&m==0)
 88             break;
 89         memset(book,0,sizeof(book));//假设全相等标记为0//book[1]表示该节点下面的元素不相等
 90         memset(a,0,sizeof(a));//该区间相等元素值
 91         for(int i=0; i<m; i++)
 92         {
 93             cin>>op>>L>>R>>z;
 94             if(op!=4) //1+,2*,3变为z,
 95                 update(1,L,R,1,n,z,op);
 96             else //*z次方
 97             {
 98                 ll ans=query(1,L,R,1,n,z)%mod;
 99                 printf("%lld\n",ans);
100             }
101         }
102     }
103     return 0;
104 }

 

 

 
posted @ 2019-12-06 19:52  抓水母的派大星  阅读(235)  评论(0编辑  收藏  举报