zoukankan      html  css  js  c++  java
  • HDU4578 Transformation (多操作线段树)

    传送门

    终于过了这道题。。

    要注意标记之间的影响,和add操作时更新求和的顺序。

    same 区间每个数设置为x标记   

    mult  区间每个数乘x标记

    add  区间每个数加x标记

    ①:当打same标记时,mult标记和add标记就没用了,要初始化。

    ②:当打mult标记时,add标记也要乘相应的值。

    ---------------求和可以递推过来---------------

    1次方求和就正常求和

    即:sum1[rt]=sum1[rt]+(r-l+1)*val;

    2次方 可以由 (x+val)= x2+val2+2*x*val

    即:sum2[rt]=sum2[rt]+2*sum1[rt]*val+(r-l+1)*val*val;

    3次方 可以由 (x+val)= x3+val3+3*x2*val+3*x*val2

    即:sum3[rt]=sum3[rt]+(r-l+1)*val*val*val+3*sum2[rt]*val+3*sum1[rt]*val*val;

    再次注意  add求和要按照sum3,sum2, sum1的顺序!

    算是又对取模有了一点了解。。

    a*b*c*d  取模为  (a*b%mod) * (c*d%mod) %mod

    a+b*c*d+3*a*b*c*d  取模为 (a + (b*c)%mod*d + 3*((a*b)%mod)*((c*d)%mod)%mod)%mod

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int mod=10007;
      5 const int maxx=100010;
      6 
      7 ll add[maxx<<2],mult[maxx<<2],same[maxx<<2];
      8 ll sum1[maxx<<2],sum2[maxx<<2],sum3[maxx<<2];
      9 
     10 int n,m,sum;
     11 
     12 void pushup(int rt) {
     13     sum1[rt]=(sum1[rt<<1]+sum1[rt<<1|1])%mod;
     14     sum2[rt]=(sum2[rt<<1]+sum2[rt<<1|1])%mod;
     15     sum3[rt]=(sum3[rt<<1]+sum3[rt<<1|1])%mod;
     16 }
     17 
     18 void build(int l,int r,int rt) {
     19     add[rt]=same[rt]=0;
     20     mult[rt]=1;
     21     if(l==r) {
     22         sum1[rt]=sum2[rt]=sum3[rt]=0;
     23         return;
     24     }
     25     int mid=(l+r)>>1;
     26     build(l,mid,rt<<1);
     27     build(mid+1,r,rt<<1|1);
     28     pushup(rt);
     29 }
     30 
     31 void pushdown(int rt,int len) {  //下传标记
     32     if(same[rt]) {
     33         sum1[rt<<1]=(len-(len>>1))*same[rt]%mod;
     34         sum1[rt<<1|1]=(len>>1)*same[rt]%mod;
     35         sum2[rt<<1]=((len-(len>>1))*same[rt]%mod)*same[rt]%mod;
     36         sum2[rt<<1|1]=((len>>1)*same[rt]%mod)*same[rt]%mod;
     37         sum3[rt<<1]=((len-(len>>1))*same[rt]%mod)*(same[rt]*same[rt]%mod)%mod;
     38         sum3[rt<<1|1]=((len>>1)*same[rt]%mod)*(same[rt]*same[rt]%mod)%mod;
     39         same[rt<<1]=same[rt<<1|1]=same[rt];
     40         add[rt<<1]=add[rt<<1|1]=0;  //也需要改变
     41         mult[rt<<1]=mult[rt<<1|1]=1; //也需要改变
     42         same[rt]=0;
     43     }
     44     if(mult[rt]!=1) {
     45         mult[rt<<1]=mult[rt<<1]*mult[rt]%mod;
     46         mult[rt<<1|1]=mult[rt<<1|1]*mult[rt]%mod;
     47         add[rt<<1]=add[rt<<1]*mult[rt]%mod; //改变
     48         add[rt<<1|1]=add[rt<<1|1]*mult[rt]%mod;  //改变
     49         sum1[rt<<1]=sum1[rt<<1]*mult[rt]%mod;
     50         sum1[rt<<1|1]=sum1[rt<<1|1]*mult[rt]%mod;
     51         sum2[rt<<1]=(sum2[rt<<1]*mult[rt]%mod)*mult[rt]%mod;
     52         sum2[rt<<1|1]=(sum2[rt<<1|1]*mult[rt]%mod)*mult[rt]%mod;
     53         sum3[rt<<1]=(sum3[rt<<1]*mult[rt]%mod)*(mult[rt]*mult[rt]%mod)%mod;
     54         sum3[rt<<1|1]=(sum3[rt<<1|1]*mult[rt]%mod)*(mult[rt]*mult[rt]%mod)%mod;
     55         mult[rt]=1;
     56     }
     57     if(add[rt]) {
     58         add[rt<<1]=(add[rt<<1]+add[rt])%mod;
     59         add[rt<<1|1]=(add[rt<<1|1]+add[rt])%mod;
     60         sum3[rt<<1]=(sum3[rt<<1]+3*sum2[rt<<1]*add[rt]%mod+3*(sum1[rt<<1]*add[rt]%mod)*add[rt]%mod+(add[rt]*add[rt]%mod)*(add[rt]*(len-(len>>1))%mod))%mod;
     61         sum3[rt<<1|1]=(sum3[rt<<1|1]+3*sum2[rt<<1|1]*add[rt]%mod+3*(sum1[rt<<1|1]*add[rt]%mod)*add[rt]%mod+(add[rt]*add[rt]%mod)*(add[rt]*(len>>1)%mod))%mod;
     62         sum2[rt<<1]=(sum2[rt<<1]+2*sum1[rt<<1]*add[rt]%mod+(add[rt]*add[rt]%mod)*(len-(len>>1))%mod)%mod;
     63         sum2[rt<<1|1]=(sum2[rt<<1|1]+2*sum1[rt<<1|1]*add[rt]%mod+(add[rt]*add[rt]%mod)*(len>>1)%mod)%mod;
     64         sum1[rt<<1]=(sum1[rt<<1]+(len-(len>>1))*add[rt]%mod)%mod;
     65         sum1[rt<<1|1]=(sum1[rt<<1|1]+(len>>1)*add[rt]%mod)%mod;
     66         add[rt]=0;
     67     }
     68 }
     69 
     70 void updata(int L,int R, int val,int op,int l,int r,int rt) {
     71     if(L<=l&&R>=r) {
     72         if(op==3) {
     73             same[rt]=val;
     74             mult[rt]=1;  //改变
     75             add[rt]=0;   //改变
     76             sum1[rt]=(r-l+1)*val%mod;
     77             sum2[rt]=((r-l+1)*val%mod)*val%mod;
     78             sum3[rt]=((r-l+1)*val%mod)*(val*val%mod)%mod;
     79         } else if(op==2) {
     80             mult[rt]=mult[rt]*val%mod;
     81             add[rt]=add[rt]*val%mod; //改变
     82             sum1[rt]=sum1[rt]*val%mod;
     83             sum2[rt]=(sum2[rt]*val%mod)*val%mod;
     84             sum3[rt]=(sum3[rt]*val%mod)*(val*val%mod)%mod;
     85         } else if(op==1) {
     86             add[rt]=(add[rt]+val)%mod;
     87             sum3[rt]=(sum3[rt]+3*sum2[rt]*val%mod+3*(sum1[rt]*val%mod)*val%mod+(((r-l+1)*val%mod)*(val*val%mod)%mod))%mod;
     88             sum2[rt]=(sum2[rt]+2*sum1[rt]*val%mod+((r-l+1)*val%mod)*val%mod)%mod;
     89             sum1[rt]=(sum1[rt]+(r-l+1)*val%mod)%mod;
     90         }
     91         return;
     92     }
     93     pushdown(rt,r-l+1);
     94     int mid=(l+r)>>1;
     95     if(L<=mid) updata(L,R,val,op,l,mid,rt<<1);
     96     if(R>mid) updata(L,R,val,op,mid+1,r,rt<<1|1);
     97     pushup(rt);
     98 }
     99 
    100 ll query(int L,int R,int val,int l,int r,int rt) {
    101     if(L<=l&&R>=r) {
    102         if(val==1) {
    103             return sum1[rt]%mod;
    104         } else if(val==2) {
    105             return sum2[rt]%mod;
    106         } else return sum3[rt]%mod;
    107     }
    108     ll sum=0;
    109     pushdown(rt,r-l+1);
    110     int mid=(l+r)>>1;
    111     if(L<=mid) sum=(sum+query(L,R,val,l,mid,rt<<1))%mod;
    112     if(R>mid) sum=(sum+query(L,R,val,mid+1,r,rt<<1|1))%mod;
    113     return sum;
    114 }
    115 
    116 int main() {
    117     while(~scanf("%d%d",&n,&m)) {
    118         if(n==0&&m==0) break;
    119         build(1,n,1);
    120         while(m--) {
    121             int op,x,y,val;
    122             scanf("%d%d%d%d",&op,&x,&y,&val);
    123             if(op==4) {
    124                 printf("%lld
    ",query(x,y,val,1,n,1));
    125             }
    126             else updata(x,y,val,op,1,n,1);
    127         }
    128     }
    129 }
    View Code

     

  • 相关阅读:
    没有一个计时器控制在VB6计时器功能
    检测系统范围内的鼠标事件
    c# Com
    tcpdump
    dd
    dumpe/dumpe2fs/e2fsck
    fdisk
    mkswap/swapon/swapoff/free
    mkfs/mk2fs/fsck/e2fsck/tune2fs/blkid
    parted
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/11156998.html
Copyright © 2011-2022 走看看