当前位置: 代码迷 >> 综合 >> hdu-4578-Transformation-线段树
  详细解决方案

hdu-4578-Transformation-线段树

热度:80   发布时间:2023-12-19 10:35:31.0

当一道题目,使用__int64超时,使用int就能A的时候,我想,这个题,不是一个好题。。。。。

add[i]:记录加的lazy标记

mul[i]:记录乘的lazy标记

num[i]:记录数的lazy标记

sum[i][j]:第i段,j次方的和。

除去lazy标记的下放,这完全就是一道水的线段树的题目。。。

lazy标记如何下放呢?

1,首先查看num标记,如果存在,果断下放。

2,然后mul标记和add标记一起下放。

#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;
}


  相关解决方案