zoukankan      html  css  js  c++  java
  • hdu4578 Transformation

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578

    题目大意:n个数(初始为0)m个操作,操作类型有4种,操作1把区间的每个数+a,操作2把区间的每个数*a.,操作3把区间的每个数=a,操作4,查询区间每个数p次方的和(1<=p<=3)

    解:

    线段树解决,考虑的问题有两个:

    1、赋值操作一定放在前面,然后有 先+后* 和 先*后+ 效果不一样

    2、p次方和

    对于问题一,采用先*后+的方式,这样在加入一个乘法标记的时候只用给之前的加标记乘上新标记的数即可

    对于问题二,把(a+b)^2 和 (a+b)^3 展开,就知道怎么处理了

      1 /*
      2  * Problem:  
      3  * Author:  SHJWUDP
      4  * Created Time:  2015/11/3 星期二 15:20:05
      5  * File Name: 1001.cpp
      6  * State: 
      7  * Memo: 
      8  */
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <vector>
     12 #include <cstring>
     13 #include <algorithm>
     14 #include <list>
     15 
     16 using namespace std;
     17 
     18 const int MOD=1e4+7;
     19 
     20 struct SegmentTree {
     21     struct Node {
     22         vector<long long> sum;
     23         vector<long long> delay;
     24         Node():sum(3), delay(3){ delay[1]=1; }
     25         void relax() {
     26             for(auto & x : sum) x%=MOD;
     27             for(auto & x : delay) x%=MOD;
     28         }
     29     };
     30     int n;
     31     vector<Node> c;
     32     SegmentTree(int _n):n(_n),c(_n<<2){}
     33 #define lson l, m, rt<<1
     34 #define rson m+1, r, rt<<1|1
     35     void deal(Node & o, pair<int, int> p, int range) {
     36         auto & d=o.delay;
     37         long long b1=p.second, b2=b1*b1, b3=b2*b1;
     38         switch(p.first) {
     39         case 0:
     40         {
     41             long long a1=o.sum[0], a2=o.sum[1];
     42             o.sum[2]+=3*a1*b2+3*a2*b1+b3*range;
     43             o.sum[1]+=2*a1*b1+b2*range;
     44             o.sum[0]+=b1*range;
     45             d[0]+=b1;
     46             break;
     47         }
     48         case 1:
     49             o.sum[2]*=b3;
     50             o.sum[1]*=b2;
     51             o.sum[0]*=b1;
     52             d[0]*=b1;
     53             d[1]*=b1;
     54             break;
     55         case 2: 
     56             o.sum[2]=b3*range;
     57             o.sum[1]=b2*range;
     58             o.sum[0]=b1*range;
     59             d[0]=0; d[1]=1;
     60             d[2]=b1;
     61             break;
     62         }
     63         o.relax();
     64     }
     65     void pushDown(int l, int m, int r, int rt) {
     66         for(int i=2; i>=0; --i) {
     67             if(!c[rt].delay[i]) continue;
     68             if(i==1 && c[rt].delay[i]==1) continue;
     69             deal(c[rt<<1], {i, c[rt].delay[i]}, m-l+1);
     70             deal(c[rt<<1|1], {i, c[rt].delay[i]}, r-m);
     71         }
     72         c[rt].delay={0, 1, 0};
     73     }
     74     void pushUp(int rt) {
     75         for(int i=0; i<3; ++i) {
     76             c[rt].sum[i]=(c[rt<<1].sum[i]+c[rt<<1|1].sum[i])%MOD;
     77         }
     78     }
     79     void update(int L, int R, pair<int, int> x, int l, int r, int rt) {
     80         if(L<=l && r<=R) {
     81             deal(c[rt], x, r-l+1);
     82         } else {
     83             int m=(l+r)>>1;
     84             pushDown(l, m, r, rt);
     85             if(L<=m) update(L, R, x, lson);
     86             if(m<R) update(L, R, x, rson);
     87             pushUp(rt);
     88         }
     89     }
     90     int query(int L, int R, int x, int l, int r, int rt) {
     91         if(L<=l && r<=R) {
     92             return c[rt].sum[x];
     93         } else {
     94             int m=(l+r)>>1;
     95             pushDown(l, m, r, rt);
     96             int ret=0;
     97             if(L<=m) ret=query(L, R, x, lson);
     98             if(m<R) ret=(ret+query(L, R, x, rson))%MOD;
     99             return ret;
    100         }
    101     }
    102 };
    103 
    104 int main() {
    105 #ifndef ONLINE_JUDGE
    106     freopen("in", "r", stdin);
    107     freopen("out", "w", stdout);
    108 #endif
    109     int n, m;
    110     while(scanf("%d%d", &n, &m), n||m) {
    111         SegmentTree st(n);
    112         while(m--) {
    113             int op, a, b, c;
    114             scanf("%d%d%d%d", &op, &a, &b, &c);
    115             --a; --b;
    116     //        cout<<"<----------------->"<<endl;
    117             if(op==4) {
    118                 printf("%d
    ", st.query(a, b, c-1, 0, st.n-1, 1));
    119             } else {
    120                 st.update(a, b, {op-1, c}, 0, st.n-1, 1);
    121             }
    122         }
    123     }
    124     return 0;
    125 }
    View Code
  • 相关阅读:
    虚拟主机导入MySQL出现Unknown character set: ‘utf8mb4’
    解决导入MySQL数据库提示"Unknown character set: 'utf8mb4'"错误
    在js中怎样获得checkbox里选中的多个值?
    CSharp设计模式读书笔记(0):设计原则(学习难度:★★☆☆☆,使用频率:★★★★★)
    how to install maven and svn plugin into eclipse 3.6
    三个月不编程,能力下降80%
    maven管理的struts2spring3mybatisfreemarker框架整合
    Wiki: JavaHL for subversion & ubuntu lucid
    重装系统要装的库包 for ubuntu lucid
    Q for Eclipse is an Apache Maven plugin for the Eclipse IDE
  • 原文地址:https://www.cnblogs.com/shjwudp/p/4934626.html
Copyright © 2011-2022 走看看