HDOJ 4578 && 2013杭州邀请赛

Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 1169    Accepted Submission(s): 249


Problem Description
Yuanfang is puzzled with the question below: 
There are n integers, a 1, a 2, …, a n. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between a x and a y inclusive. In other words, do transformation a k<---a k+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between a x and a y inclusive. In other words, do transformation a k<---a k×c, k = x,x+1,…,y.
Operation 3: Change the numbers between a x and a y to c, inclusive. In other words, do transformation a k<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between a x and a y inclusive. In other words, get the result of a x p+a x+1 p+…+a y  p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him. 
 

Input
There are no more than 10 test cases.
For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.
Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)
The input ends with 0 0.
 

Output
For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.
 

Sample Input
  
  
5 5 3 3 5 7 1 2 4 4 4 1 5 2 2 2 5 8 4 3 5 3 0 0
 

Sample Output
  
  
307 7489
 
Source


一道赤裸裸的线段树,就看你写得出来不?
根据航神的思路,终于写出了这棵优雅的线段树。
题目中有4种命令,1:给区间[a,b]都加上个c。2:给区间[a , b]都乘上c。3:区间[a,b]内所有元素全赋为c。4:求区间的p次方和。
我们用a数组记录一次方和,二次方和,三次方和。
用两个标记add和multi,第一个操作可视为吧区间内各元素乘1加c,即add = c ,multi = 1;第二个操作可视为区间内各元素乘c加0,即add= 0 ,multi = c;
第三个操作可视为区间内各元素乘0加c,即add = c , multi  = 0。
然后随着update去维护a[3]的域。
把pushdown看成对其子树的update
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <cctype>
#include <vector>
#include <queue>
#include <set>


using namespace std;
//#define Online_Judge
#define outstars cout << "***********************" << endl;
#define clr(a,b) memset(a,b,sizeof(a))
#define lson l , mid  , rt << 1
#define rson mid + 1 , r , rt << 1|1
#define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)
#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)
#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)
#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)
#define mid ((l + r) >> 1)
const int MAXN = 100000 + 100;
const int maxw = 10000000 + 20;
const int MAXNNODE = 10000 +10;
const long long LLMAX = 0x7fffffffffffffffLL;
const long long LLMIN = 0x8000000000000000LL;
const int INF = 0x7fffffff;
const int IMIN = 0x80000000;
#define eps 1e-8
#define mod 10007
typedef long long LL;
const double PI = acos(-1.0);
typedef double D;
void update(int L ,int R , int add , int multi , int l , int r , int rt);
struct Node
{
    int  l , r , add , multi;
    int a[4];
}tree[4 * MAXN];
void build(int l , int r , int rt)
{
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].add = 0;
    tree[rt].multi = 1;
    FORR(i , 1 , 3)tree[rt].a[i] = 0;
    if(l == r)return;
    build(lson);
    build(rson);
}
void pushup(int rt)
{
    FORR(i , 1 , 3)tree[rt].a[i] = (tree[rt<< 1].a[i] + tree[rt << 1|1].a[i])% mod;
}
void pushdown(int rt)
{
    update(tree[rt << 1].l , tree[rt << 1].r , tree[rt].add , tree[rt].multi , tree[rt << 1].l , tree[rt << 1].r , rt << 1);
    update(tree[rt << 1|1].l , tree[rt << 1|1].r , tree[rt].add , tree[rt].multi , tree[rt << 1|1].l , tree[rt << 1|1].r , rt << 1|1);
    tree[rt].add = 0;
    tree[rt].multi = 1;

}
void update(int L ,int R , int add , int multi , int l , int r , int rt)
{
    if(L <= l&& R >= r)
    {
        if(multi != 1)
        {
            tree[rt].add = tree[rt].add * multi % mod;
            tree[rt].multi = tree[rt].multi * multi % mod;

            tree[rt].a[1] = tree[rt].a[1] * multi % mod ;
            tree[rt].a[2] = tree[rt].a[2] * multi % mod * multi % mod;
            tree[rt].a[3] = tree[rt].a[3] * multi % mod * multi % mod* multi % mod;
        }
        if(add)
        {
            tree[rt].add = (tree[rt].add + add) % mod;
            tree[rt].a[3] =  (tree[rt].a[3] + 3 * tree[rt].a[2] % mod * add % mod + 3 * tree[rt].a[1] % mod * add % mod *add % mod + (r - l + 1)% mod * add % mod *add % mod * add % mod)%mod;///和的立方展开
            tree[rt].a[2] = (tree[rt].a[2] + 2 * tree[rt].a[1] % mod * add % mod + (r - l + 1) % mod * add %mod *add % mod) % mod;///和的平方展开
            tree[rt].a[1] = (tree[rt].a[1] + (r - l + 1) % mod * add % mod)%mod;
        }
        return ;
    }
    pushdown(rt);
    if(L <= mid)update(L ,R , add , multi , lson);
    if(R > mid)update(L ,R , add , multi , rson);
    pushup(rt);
}
int query(int L , int R ,int c , int l , int r , int  rt)
{
    if(L <= l && R >= r)return tree[rt].a[c];
    pushdown(rt);
    int ans = 0;
    if(L <= mid)ans =(ans + query(L ,R , c ,lson))%mod;
    if(R > mid)ans = (ans + query(L , R ,c , rson)) % mod;
    return ans;

}
int main()
{
    //ios::sync_with_stdio(false);
#ifdef Online_Judge
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif // Online_Judge
    int n , m , i, j , a , b , c , op;
    while(scanf("%d%d" , &n , &m) != EOF&&(m|| n))
    {
        build(1 , n , 1);
        FORR(i , 1 , m)
        {
            scanf("%d%d%d%d",&op,  &a , &b , &c);
            if(op == 1)update(a , b ,c , 1 , 1 ,n , 1);
            else if(op == 2)update(a , b ,0 , c , 1 , n , 1);
            else if(op == 3)update(a , b , c , 0 , 1 , n , 1);
            else printf("%d\n" , query(a , b , c , 1 , n , 1));
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值