HDU 4578 线段树复杂题

题目大意:

题意:有一个序列,有四种操作:

1:区间[l,r]内的数全部加c。

2:区间[l,r]内的数全部乘c。

3:区间[l,r]内的数全部初始为c。

4:询问区间[l,r]内所有数的P次方之和。

这里p可以等于1,2,3三种情况,所以我们需要建立3个数组,当然这里其实只用一个sum[4*N][3]的2维数组其实更好

to[],add[],mul[]为三个懒惰标记to[]先于另外两个,每次做完to[],另外两个标记就要将其初始化

对于mul[]来说,每次执行,add[cur]*=mul[cur]也要随之增加

因为这道题目数过大,需要求mod 10007的值

因为这个我把代码从上午看到了下午简直要疯了

int最大值2147483647

你必须每执行一步操作都需要mod一次,*2后,10007*2*10007 int还不至于爆掉,但也差不多

但是若*3之后那肯定要是再碰到一个超大数,那就GG了

所以每次乘法算完都mod一次吧,每次做mod带上括号是一个好习惯~~

  1 //这鬼题目里面最好每执行一次乘法就mod一次,不然可能int要爆掉导致报错,尤其是我在fun_add()中改错改了一天才发现是这个原因

  2 #include <cstdio>

  3 #include <cstring>

  4 using namespace std;

  5 #define N 100005

  6 #define mod 10007

  7 int sum[4*N][3],add[4*N],to[4*N],mul[4*N];

  8 void update(int cur)

  9 {

 10     sum[cur][0]=(sum[cur<<1][0]+sum[cur<<1|1][0])%mod;

 11     sum[cur][1]=(sum[cur<<1][1]+sum[cur<<1|1][1])%mod;

 12     sum[cur][2]=(sum[cur<<1][2]+sum[cur<<1|1][2])%mod;

 13 }

 14 void build(int cur,int x,int y)

 15 {

 16     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;

 17     add[cur]=0,to[cur]=0,mul[cur]=1;

 18     if(x==y){

 19         sum[cur][0]=sum[cur][1]=sum[cur][2]=0;

 20         return;

 21     }

 22     build(ls,x,mid);

 23     build(rs,mid+1,y);

 24     update(cur);

 25 }

 26 void fun_mul(int cur,int x,int y,int val)

 27 {

 28     mul[cur]*=val;

 29     mul[cur]%=mod;

 30     add[cur]*=val;

 31     add[cur]%=mod;

 32 

 33     int t1=val*val%mod;

 34     int t2=t1*val%mod;

 35     sum[cur][0]=sum[cur][0]*val;

 36     sum[cur][0]%=mod;

 37 

 38     sum[cur][1]=sum[cur][1]*t1;

 39     sum[cur][1]%=mod;

 40 

 41     sum[cur][2]=sum[cur][2]*t2;

 42     sum[cur][2]%=mod;

 43 }

 44 void fun_add(int cur,int x,int y,int val)

 45 {

 46     add[cur]+=val;

 47     add[cur]%=mod;

 48     int t1=sum[cur][0];

 49     int t2=sum[cur][1];

 50     int tmp1=val*val%mod;

 51     int tmp2=val*tmp1%mod;

 52     sum[cur][0]+=(y-x+1)*val;

 53     sum[cur][0]%=mod;

 54 

 55     sum[cur][1]+=(y-x+1)*tmp1%mod+((2*val)%mod)*t1%mod;

 56     sum[cur][1]%=mod;

 57 

 58     sum[cur][2]+=((3*val)%mod)*t2%mod+3*tmp1*t1%mod+(y-x+1)*tmp2%mod;

 59     sum[cur][2]%=mod;

 60 }

 61 void fun_to(int cur,int x,int y,int val)

 62 {

 63     mul[cur]=1,add[cur]=0,to[cur]=val%mod;

 64     int t1=val*val%mod;

 65     int t2=t1*val%mod;

 66     sum[cur][0]=(y-x+1)*val%mod;

 67     sum[cur][1]=(y-x+1)*t1%mod;

 68     sum[cur][2]=(y-x+1)*t2%mod;

 69 }

 70 void pushdown(int cur,int x,int y)

 71 {

 72     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;

 73     if(to[cur]){

 74         //to[ls]=to[rs]=to[cur];

 75         fun_to(ls,x,mid,to[cur]);

 76         fun_to(rs,mid+1,y,to[cur]);

 77         to[cur]=0;

 78     }

 79     if(mul[cur]>1){

 80         //mul[ls]*=mul[cur],mul[rs]*=mul[cur];

 81         fun_mul(ls,x,mid,mul[cur]);

 82         fun_mul(rs,mid+1,y,mul[cur]);

 83         mul[cur]=1;

 84     }

 85     if(add[cur]){

 86         //add[ls]+=add[cur],add[rs]+=add[cur];

 87         fun_add(ls,x,mid,add[cur]);

 88         fun_add(rs,mid+1,y,add[cur]);

 89         add[cur]=0;

 90     }

 91 }

 92 void change(int cur,int x,int y,int s,int t,int op,int v)

 93 {

 94     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;

 95     if(x>=s&&y<=t){

 96         if(op==1) fun_add(cur,x,y,v);

 97         if(op==2) fun_mul(cur,x,y,v);

 98         if(op==3) fun_to(cur,x,y,v);

 99         return;

100     }

101     pushdown(cur,x,y);

102     if(mid>=s) change(ls,x,mid,s,t,op,v);

103     if(mid+1<=t) change(rs,mid+1,y,s,t,op,v);

104     update(cur);

105 }

106 void query(int cur,int x,int y,int s ,int t,int p,int &ans)

107 {

108     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;

109     if(x>=s&&y<=t){

110         ans+=sum[cur][p-1];

111         ans%=mod;

112         return;

113     }

114     pushdown(cur,x,y);

115     if(mid>=s) query(ls,x,mid,s,t,p,ans);

116     if(mid+1<=t) query(rs,mid+1,y,s,t,p,ans);

117 }

118 int main()

119 {

120     int n,m,op,x,y,p;

121     while(scanf("%d%d",&n,&m),n+m){

122         build(1,1,n);

123         for(int i=0;i<m;i++){

124             scanf("%d%d%d%d",&op,&x,&y,&p);

125             if(op==4){

126                 int ans=0;

127                 //printf("%d\n",0);

128                 query(1,1,n,x,y,p,ans);

129                 printf("%d\n",ans%mod);

130             }

131             else change(1,1,n,x,y,op,p);

132         }

133     }

134 }

 

你可能感兴趣的:(HDU)