hdu4578 Transformation【线段树】
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
超麻烦的线段树 一共四种操作
加 乘 赋值 幂
分别用一个数组表示
关键在于下方pushdown的操作
赋值的时候就直接下放 保存的幂也直接求
加和乘的操作一起下放 用平方和立方公式来求sum
自己写的不知道为什么RE了 查了半天查不出来 而且好复杂懒得查了.....
下面是题解的代码
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 110000
#define lmin 1
#define rmax n
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define root lmin,rmax,1
#define now l,r,rt
#define int_now int l,int r,int rt
#define INF 99999999
#define LL int
#define mod 10007
LL add[maxn*4];
LL mul[maxn*4];
LL num[maxn*4];
LL sum[maxn*4][4];
void push_up(int_now)
{
for(int i=1; i<=3; i++)
sum[rt][i]=(sum[rt<<1][i]+sum[rt<<1|1][i])%mod;
}
void push_down(int_now)
{
if(l==r)return;
int ll=(r+l)/2-l+1;
int rr=r-(r+l)/2;
if(num[rt] != 0)
{
num[rt<<1] = num[rt<<1|1] = num[rt];
add[rt<<1] = add[rt<<1|1] = 0;
mul[rt<<1] = mul[rt<<1|1] = 1;
sum[rt<<1][1] = (ll)*num[rt<<1]%mod;
sum[rt<<1][2] = (ll)*num[rt<<1]%mod*num[rt<<1]%mod;
sum[rt<<1][3] = (ll)*num[rt<<1]%mod*num[rt<<1]%mod*num[rt<<1]%mod;
sum[(rt<<1)|1][1] = (rr)*num[rt<<1|1]%mod;
sum[(rt<<1)|1][2] = (rr)*num[rt<<1|1]%mod*num[rt<<1|1]%mod;
sum[(rt<<1)|1][3] = (rr)*num[rt<<1|1]%mod*num[rt<<1|1]%mod*num[rt<<1|1]%mod;
num[rt] = 0;
}
if(add[rt] != 0 || mul[rt] != 1)
{
add[rt<<1] = ( mul[rt]*add[rt<<1]%mod + add[rt] )%mod;
mul[rt<<1] = mul[rt<<1]*mul[rt]%mod;
int sum1,sum2,sum3;
sum1 = (sum[rt<<1][1]*mul[rt]%mod + (ll)*add[rt]%mod)%mod;
sum2 = (mul[rt] * mul[rt] % mod * sum[rt<<1][2] % mod + 2*add[rt]*mul[rt]%mod * sum[rt<<1][1]%mod + (ll)*add[rt]%mod*add[rt]%mod)%mod;
sum3 = mul[rt] * mul[rt] % mod * mul[rt] % mod * sum[rt<<1][3] % mod;
sum3 = (sum3 + 3*mul[rt] % mod * mul[rt] % mod * add[rt] % mod * sum[rt<<1][2]) % mod;
sum3 = (sum3 + 3*mul[rt] % mod * add[rt] % mod * add[rt] % mod * sum[rt<<1][1]) % mod;
sum3 = (sum3 + (ll)*add[rt]%mod * add[rt] % mod * add[rt] % mod) % mod;
sum[rt<<1][1] = sum1;
sum[rt<<1][2] = sum2;
sum[rt<<1][3] = sum3;
add[rt<<1|1] = ( mul[rt]*add[rt<<1|1]%mod + add[rt] )%mod;
mul[rt<<1|1] = mul[rt<<1|1] * mul[rt] % mod;
sum1 = (sum[(rt<<1)|1][1]*mul[rt]%mod + (rr)*add[rt]%mod)%mod;
sum2 = (mul[rt] * mul[rt] % mod * sum[(rt<<1)|1][2] % mod + 2*add[rt]*mul[rt]%mod * sum[(rt<<1)|1][1]%mod + (rr)*add[rt]%mod*add[rt]%mod)%mod;
sum3 = mul[rt] * mul[rt] % mod * mul[rt] % mod * sum[(rt<<1)|1][3] % mod;
sum3 = (sum3 + 3*mul[rt] % mod * mul[rt] % mod * add[rt] % mod * sum[(rt<<1)|1][2]) % mod;
sum3 = (sum3 + 3*mul[rt] % mod * add[rt] % mod * add[rt] % mod * sum[(rt<<1)|1][1]) % mod;
sum3 = (sum3 + (rr)*add[rt]%mod * add[rt] % mod * add[rt] % mod) % mod;
sum[(rt<<1)|1][1] = sum1;
sum[(rt<<1)|1][2] = sum2;
sum[(rt<<1)|1][3] = sum3;
add[rt] = 0;
mul[rt] = 1;
}
}
void creat(int_now)
{
add[rt]=0;
mul[rt]=1;
num[rt]=0;
for(int i=1; i<=3; i++)sum[rt][i]=0;
if(l!=r)
{
creat(lson);
creat(rson);
}
}
void update(int ll,int rr,int x,int k,int_now)
{
if(ll>r||rr<l)return;
if(ll<=l&&rr>=r)
{
x=x%mod;
if(k==1)
{
add[rt]=(add[rt]+x)%mod;
sum[rt][3]=(sum[rt][3]+3*sum[rt][2]%mod*x%mod+3*sum[rt][1]%mod*x%mod*x%mod+x*x%mod*x%mod*(r-l+1)%mod)%mod;
sum[rt][2]=(sum[rt][2]+(r-l+1)*x%mod*x%mod+2*x%mod*sum[rt][1]%mod)%mod;
sum[rt][1]=(sum[rt][1]+x*(r-l+1)%mod)%mod;
}
else if(k==2)
{
mul[rt]=(mul[rt]*x)%mod;
add[rt]=(add[rt]*x)%mod;
for(int i=1; i<=3; i++)
{
int j=i;
LL ans=1;
while(j--)ans=(ans*x)%mod;
sum[rt][i]=(sum[rt][i]*ans)%mod;
}
}
else
{
num[rt]=x;
mul[rt]=1;
add[rt]=0;
for(int i=1; i<=3; i++)
{
int j=i;
LL ans=1;
while(j--)ans=(ans*x)%mod;
sum[rt][i]=(ans*(r-l+1)%mod)%mod;
}
}
return;
}
push_down(now);
update(ll,rr,x,k,lson);
update(ll,rr,x,k,rson);
push_up(now);
}
LL query(int ll,int rr,int p,int_now)
{
if(ll>r||rr<l)return 0;
if(ll<=l&&rr>=r)
{
return sum[rt][p];
}
push_down(now);
return (query(ll,rr,p,lson)+query(ll,rr,p,rson))%mod;
}
int main()
{
int n,m,k,a,b,c;
while(~scanf("%d%d",&n,&m)&&(n||m))
{
creat(root);
while(m--)
{
scanf("%d%d%d%d",&k,&a,&b,&c);
if(k<=3)
{
update(a,b,c,k,root);
}
else
{
printf("%d\n",query(a,b,c,root));
}
}
}
return 0;
}
RE的代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#define inf 1e18
using namespace std;
const int maxn = 110005;
const int mod = 10007;
int m, n;
long long sum[maxn << 2][4], lazyadd[maxn<<2], lazymul[maxn<<2], lazynum[maxn<<2];
void pushup(int rt)
{
for(int i = 1; i <= 3; i++){
sum[rt][i] = (sum[rt << 1][i] + sum[rt << 1|1][i]) % mod;
}
}
void build(int l, int r, int rt)
{
lazyadd[rt] = 0;
lazymul[rt] = 1;
lazynum[rt] = 0;
for(int i = 1; i <= 3; i++)
sum[rt][i] = 0;
if(l == r) return;
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
}
void pushdown(int l, int r, int rt)
{
if(l == r) return;
int m = (l + r) / 2;
int lnum = m - l + 1, rnum = r - m;
if(lazynum[rt]){//ж╠╫соб╥е
lazynum[rt << 1] = lazynum[rt<<1|1] = lazynum[rt];
lazyadd[rt<<1] = lazyadd[rt<<1|1] = 0;
lazymul[rt<<1] = lazymul[rt<<1|1] = 1;
sum[rt<<1][1] = lnum * lazynum[rt<<1] % mod;
sum[rt<<1][2] = lnum * lazynum[rt<<1] % mod * lazynum[rt<<1] % mod;
sum[rt<<1][3] = lnum * lazynum[rt<<1] % mod * lazynum[rt<<1] % mod * lazynum[rt<<1] % mod;
sum[rt<<1|1][1] = rnum * lazynum[rt<<1|1] % mod;
sum[rt<<1|1][2] = rnum * lazynum[rt<<1|1] % mod * lazynum[rt<<1|1] % mod;
sum[rt<<1|1][3] = rnum * lazynum[rt<<1|1] % mod * lazynum[rt<<1|1] % mod * lazynum[rt<<1|1] % mod;
lazynum[rt] = 0;
}
if(lazyadd[rt] || lazymul[rt] != 1){
lazyadd[rt<<1] = (lazymul[rt] * lazyadd[rt<<1] % mod + lazyadd[rt])% mod;
lazymul[rt<<1] = lazymul[rt] * lazymul[rt<<1] % mod;
int sum1 = (sum[rt<<1][1] * lazymul[rt] % mod + lnum * lazyadd[rt] % mod) % mod;
int sum2 = (sum[rt<<1][2] * lazymul[rt] % mod * lazymul[rt] % mod + 2 * lazyadd[rt] * lazymul[rt] % mod * sum[rt<<1][1] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
int sum3 = (sum[rt<<1][3] * lazymul[rt] % mod * lazymul[rt] % mod * lazymul[rt] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
sum3 = (sum3 + 3 * lazymul[rt] * lazyadd[rt] % mod * lazyadd[rt] % mod * sum[rt<<1][1] % mod) % mod;
sum3 = (sum3 + 3 * lazymul[rt] * lazymul[rt] % mod * lazyadd[rt] % mod * sum[rt<<1][2] % mod) % mod;
sum[rt<<1][1] = sum1;
sum[rt<<1][2] = sum2;
sum[rt<<1][3] = sum3;
lazyadd[rt<<1|1] = (lazymul[rt] * lazyadd[rt<<1|1] % mod + lazyadd[rt]) % mod;
lazymul[rt<<1|1] = lazymul[rt] * lazymul[rt<<1|1] % mod;
sum1 = (sum[rt<<1|1][1] * lazymul[rt] % mod + lnum * lazyadd[rt] % mod) % mod;
sum2 = (sum[rt<<1|1][2] * lazymul[rt] % mod * lazymul[rt] % mod + 2 * lazyadd[rt] * lazymul[rt] % mod * sum[rt<<1|1][1] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
sum3 = (sum[rt<<1|1][3] * lazymul[rt] % mod * lazymul[rt] % mod * lazymul[rt] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
sum3 = (sum3 + 3 * lazymul[rt] * lazyadd[rt] % mod * lazyadd[rt] % mod * sum[rt<<1|1][1] % mod) % mod;
sum3 = (sum3 + 3 * lazymul[rt] * lazymul[rt] % mod * lazyadd[rt] % mod * sum[rt<<1|1][2] % mod) % mod;
sum[rt<<1|1][1] = sum1;
sum[rt<<1|1][2] = sum2;
sum[rt<<1|1][3] = sum3;
lazyadd[rt] = 0;
lazymul[rt] = 1;
}
}
void update(int L, int R, int x, int k, int l, int r, int rt)
{
if(L > r || R < l)return;
if(L <= l && R >= r){
x = x % mod;
if(k == 1){
lazyadd[rt] = (lazyadd[rt] + x) % mod;
sum[rt][3] = (sum[rt][3] + 3 * sum[rt][2] % mod * x % mod + 3 * sum[rt][1] % mod * x % mod * x % mod + (r - l + 1) * x % mod * x % mod * x % mod) % mod;
sum[rt][2] = (sum[rt][2] + 2 * sum[rt][1] % mod * x % mod + (r - l + 1) * x % mod * x % mod) % mod;
sum[rt][1] = (sum[rt][1] + (r - l + 1) * x % mod) % mod;
}
else if(k == 2){
lazymul[rt] = lazymul[rt] * x % mod;
lazyadd[rt] = lazyadd[rt] * x % mod;
for(int i = 1; i <= 3; i++){
int j = i;
long long ans = 1;
while(j--){
ans = (ans * x) % mod;
}
sum[rt][i] = (sum[rt][i] * ans) % mod;
}
}
else{
lazynum[rt] = x;
lazymul[rt] = 1;
lazyadd[rt] = 0;
for(int i = 1; i <= 3; i++){
int j = i;
long long ans = 1;
while(j--){
ans = (ans * x) % mod;
}
sum[rt][i] = (ans * (r - l + 1) % mod) % mod;
}
}
return;
}
pushdown(l, r, rt);
int m = (l + r) / 2;
update(L, R, x, k, l, m, rt<<1);
update(L, R, x, k, m + 1, r, rt<<1|1);
pushup(rt);
}
long long query(int L, int R, int p, int l, int r, int rt)
{
if(L > r || R < L) return 0;
if(L <= l && R >= r){
return sum[rt][p];
}
pushdown(l, r, rt);
int m = (l + r) / 2;
return (query(L, R, p, l, m, rt<<1) + query(L, R, p, m + 1, r, rt<<1|1)) % mod;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF && (n || m)){
build(1, n, 1);
int k, x, y, c;
for(int i = 0; i < m; i++){
scanf("%d%d%d%d", &k, &x, &y, &c);
if(k == 4){
printf("%lld\n", query(x, y, c, 1, n, 1));
}
else{
update(x, y, c, k, 1, n, 1);
}
}
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· DeepSeek智能编程
· 精选4款基于.NET开源、功能强大的通讯调试工具
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?