• HDU 4578


    Transformation

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

    Problem Description

    Yuanfang is puzzled with the question below:
    There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
    Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
    Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
    Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
    Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay 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

    解题思路

    裸线段树题目,处理情况非常多,主要问题在于乘法加法改变值的冲突对于二次方三次方线段树的维护,对于第二个问题处理方式为将求和的多项式展开可以得到
    (x+a)^2 = x^2+2ax +a^2,推得Sum2 = Sum2 + 2aSum1 + (a^2) * (区间大小), Sum3 同理。
    第一个问题在于三种操作的优先级为 改值 > 乘法 > 加法, 并在打上改值标记的时候重置乘法加法的标记,打上乘法标记的时候更新加法标记的值。
    ps: 标记下传的时候也要更新其他标记的值。

    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <map>
    #include <stack>
    #define M 10007
    #define ll long long 
    #define se second
    #define fi first
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define de(x) cout << #x << " = "<< x << endl;
    #define eps 1e-6
    
    using namespace std;
    int n, m;
    ll sum[4][1000005], col[1000005], add[1000005], mul[1000005];
    int lol, tot;
    void append(int t, int m, ll z)
    {
    	sum[3][t] = (sum[3][t] + (3 * z * (z * sum[1][t] + sum[2][t]) % M + ((z * z * z) % M)* m))% M;
    	sum[2][t] = (sum[2][t] + (2 * z * sum[1][t]) + (z * z) * m %M) % M;
    	sum[1][t] = (sum[1][t] + z * m) % M;
    }
    
    void multiply(int t, ll z)
    {
    	sum[3][t] = sum[3][t] * (z * z * z % M) % M;
    	sum[2][t] = sum[2][t] * (z * z % M) % M;
    	sum[1][t] = sum[1][t] * z % M;
    }
    
    void change(int t, int m, ll z)
    {
    	sum[1][t] = z * m % M;
    	sum[2][t] = sum[1][t] * z % M;
    	sum[3][t] = sum[2][t] * z % M;
    }
    
    void push_down(int t, int m)
    {
    	if (col[t])
    	{
    		col[t << 1] = col[t];
    		col[t << 1 | 1] = col[t];
    		mul[t << 1] = 1;
    		mul[t << 1 | 1] = 1;
    		add[t << 1] = 0;
    		add[t << 1 | 1] = 0;
    		change(t << 1, m - (m >> 1), col[t]);
    		change(t << 1 | 1, m >> 1, col[t]);
    		col[t] = 0;
    	}
    	if (mul[t] != 1)
    	{
    		mul[t << 1] = mul[t << 1] * mul[t] % M;
    		mul[t << 1 | 1] = mul[t << 1 | 1] * mul[t] % M;
    		if (add[t << 1]) add[t << 1] = (add[t << 1] * mul[t]) % M;
    		if (add[t << 1 | 1]) add[t << 1 | 1] = (add[t << 1 | 1] * mul[t]) % M;
    		multiply(t << 1, mul[t]);
    		multiply(t << 1 | 1, mul[t]);
    		mul[t] = 1;
    	}
    	if (add[t])
    	{
    		add[t << 1] = (add[t << 1] + add[t]) % M;
    		add[t << 1 | 1] = (add[t << 1 | 1] + add[t]) % M;
    
    		append(t << 1, m - (m >> 1), add[t]);
    		append(t << 1 | 1, m >> 1, add[t]);
    	
    		add[t] = 0;
    	}
    }
     
    void Add(int l, int r, int l1, int r1, int t, int z)
    {
    	if (l1 >= l && r1 <= r)
    	{
    		add[t] += z;		
    		append(t, r1 - l1 + 1, z);	
    		return;
    	}
    	push_down(t, r1 - l1 + 1);
    	int mid = (l1 + r1) >> 1;
    	if (l <= mid) Add(l, r, l1, mid, t << 1, z);
    	if (r > mid) Add(l, r, mid + 1, r1, t << 1 | 1, z);
    	for (int i = 1; i <= 3; i++)
    		sum[i][t] = (sum[i][t << 1] + sum[i][t << 1 | 1]) % M;
    }
    
    void Mul(int l, int r, int l1, int r1, int t, int z)
    {
    	if (l1 >= l && r1 <= r)
    	{
    		mul[t] = z * mul[t] % M;
    		if (add[t]) add[t] = (add[t] * z) % M;
    		multiply(t, z);
    		return;
    	}
    	push_down(t, r1 - l1 + 1);
    	int mid = (l1 + r1) >> 1;
    	if (l <= mid) Mul(l, r, l1, mid, t << 1, z);
    	if (r > mid) Mul(l, r, mid + 1, r1, t << 1 | 1, z);
    	for (int i = 1; i <= 3; i++)
    		sum[i][t] = (sum[i][t << 1] + sum[i][t << 1 | 1]) % M;
    }
    
    void Color(int l, int r, int l1, int r1, int t, int z)
    {
    	if (l1 >= l && r1 <= r)
    	{
    		col[t] = z;
    		mul[t] = 1;
    		add[t] = 0;
    		change(t, r1 - l1 + 1, z);
    		return;
    	}
    	push_down(t, r1 - l1 + 1);
    	int mid = (l1 + r1) >> 1;
    	if (l <= mid) Color(l, r, l1, mid, t << 1, z);
    	if (r > mid) Color(l, r, mid + 1, r1, t << 1 | 1, z);
    	for (int i = 1; i <= 3; i++)
    		sum[i][t] = (sum[i][t << 1] + sum[i][t << 1 | 1]) % M;
    }
    
    ll Get(int l, int r, int l1, int r1, int t, int z)
    {
    	if (l1 >= l && r1 <= r)
    	{
    		return sum[z][t];
    	}
    	push_down(t, r1 - l1 + 1);
    	ll ans = 0;
    	int mid = (l1 + r1) >> 1;
    	if (l <= mid)ans = (ans + Get(l, r, l1, mid, t << 1, z)) % M;
    	if (r > mid) ans = (ans + Get(l, r, mid + 1, r1, t << 1 | 1, z)) % M;
    	return ans % M;
    }
    
    void init()
    {
    	memset(sum, 0, sizeof(sum));
    	memset(col, 0, sizeof(col));
    	memset(add, 0, sizeof(add));
    	for (int i = 1; i <= 5 * n; i++) mul[i] = 1;
    
    	while (m--)
    	{
    		int x, y, l, r;
    		
    		scanf("%d%d%d%d", &x, &l, &r, &y);
    		if (x == 1)	Add(l, r, 1, n, 1, y);
    		else if (x == 2) Mul(l, r, 1, n, 1, y);
    		else if (x == 3) Color(l, r, 1, n, 1, y);
    		else  printf("%lld
    ", Get(l, r, 1, n, 1, y));
    	}
    }
    
    int main()
    {
    	while (~scanf("%d%d", &n, &m))
    	{
    		if (!n && !m) break;
    		init();
    	}
    	return 0;
    }
    /* 对拍了一千组数据找到的唯一 一组bug
    9 10
    1 1 2 10
    2 1 5 5
    4 1 7 2
    4 3 4 3
    4 7 8 1
    2 3 4 3
    4 2 3 3
    2 1 4 2
    1 2 7 3
    3 1 2 9
    */
    
  • 相关阅读:
    day 67 Django的view 与路由
    day65 Django模板语言
    day64 views文件
    day 64 Django 第五天 多表对多表的对应关系ORM
    Day 62 Django第三天
    Day 61 Django第二天 (orm数据库操作)
    day 60 Django第一天
    day 59 pymysql
    day 58
    三个按钮作业
  • 原文地址:https://www.cnblogs.com/seast90/p/9382244.html
Copyright © 2020-2023  润新知