shjwudp

导航

 

题目链接: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\n", 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

 

posted on 2015-11-03 22:41  shjwudp  阅读(170)  评论(0编辑  收藏  举报