zoukankan      html  css  js  c++  java
  • 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
    ",0);
    128                 query(1,1,n,x,y,p,ans);
    129                 printf("%d
    ",ans%mod);
    130             }
    131             else change(1,1,n,x,y,op,p);
    132         }
    133     }
    134 }
  • 相关阅读:
    吴裕雄--天生自然 Zookeeper学习笔记--Zookeeper 权限控制 ACL
    【机器学习】机器学习基础
    【QT】利用pyqt5实现简单界面
    【Mathtype】安装Mathtype后,word无法粘贴的问题
    【优化方法】牛顿法
    博客样式设置
    2018.8.28 练习赛
    2018.8.27 练习赛
    2018.8.26 练习赛
    2018.8.25 练习赛
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3897083.html
Copyright © 2011-2022 走看看