Hdu 4578 Transformation(细节很重要) ★
来源:互联网 发布:网络传播类杂志 编辑:程序博客网 时间:2024/06/07 20:49
题目大意:n个数(初始为0)m个操作,操作类型有4中,操作1把区间的每个数+a,操作2把区间的每个数*a.,操作3把区间的每个数=a,操作4,查询区间每个数p次方的和(1<=p<=3)
对于=更新操作:如果之前有*和+的标记,那可以忽略到*+操作,直接=操作,这个最简单,sum1=val,sum2=val*val,sum3=val*val*val;
对于*+操作:如果之前有=标记,就不能忽略了,所以pushdown优先考略=操作。 *+操作可以一起(a*x+c).
注意:在*操作更新时,要一起更新+操作,因为(x+c)*a;
然后对于 (ax+c)^3=a^3*x^3+3*a^2*c*x^2+3*a*c^2*x+c^3,也就是root[t].sum3=a^3*root[t].sum3+3*a^2*c*root[t].sum2+3*a*c^2*root[t].sum1+c^3*(root[t].r-roo[t].l+1);
同理 root[t].sum2=root[t].sum2*a^2+root[t].sum1*c*2+c^2*(root[t].r-root[t].l+1); oot[t].sum1=root[t].sum1*a+c*(root[t].r-root[t].l+1);
注意:sum3,sum2,sum1在这个操作中的顺序不能变。
注意还要手写pow,以及pushdown操作,好多细节需要考虑
pushdown操作时,遇到mul就要更新pos<<1 和pos<<1|1的mul和lazy,遇到lazy就要更新pos<<1 和pos<<1|1的lazy
细节啊!!!!
#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 100100#define MOD 1000000007const long long mod = 10007;int n,m;long long a[maxn*10];struct node{ int l,r; long long Max,Min; long long sum[4],lazy,mul,cover;} tree[maxn*4];long long pow(long long a,int b){ long long ans = 1; for(int i = 0; i < b; i++) ans = ans * a % mod; return ans;}void pushup(int pos){ if(tree[pos].l == tree[pos].r) return; for(int i = 1; i < 4; i++) tree[pos].sum[i] = (tree[pos<<1].sum[i] + tree[pos<<1|1].sum[i])%mod; //tree[pos].Max = max(tree[pos<<1].Max,tree[pos<<1|1].Max); //tree[pos].Min = min(tree[pos<<1].Min,tree[pos<<1|1].Min);}void pushdown(int pos){ if(tree[pos].l == tree[pos].r) return; if(tree[pos].cover != -1) { int l = tree[pos<<1].l,r = tree[pos<<1].r; tree[pos<<1].lazy = 0; tree[pos<<1].mul = 1; tree[pos<<1].cover = tree[pos].cover; for(int i = 1; i < 4; i++) tree[pos<<1].sum[i] = (long long)(r-l+1)*(long long)pow(tree[pos].cover,i)%mod; l = tree[pos<<1|1].l,r = tree[pos<<1|1].r; tree[pos<<1|1].lazy = 0; tree[pos<<1|1].mul = 1; tree[pos<<1|1].cover = tree[pos].cover; for(int i = 1; i < 4; i++) tree[pos<<1|1].sum[i] = (long long)(r-l+1)*(long long)pow(tree[pos].cover,i)%mod; tree[pos].cover = -1; } if(tree[pos].mul != 1) { tree[pos<<1].mul = (tree[pos<<1].mul * tree[pos].mul)%mod; tree[pos<<1].lazy = (tree[pos<<1].lazy * tree[pos].mul) % mod; for(int i = 1; i < 4; i++) tree[pos<<1].sum[i] = (tree[pos<<1].sum[i] * (long long)pow(tree[pos].mul,i))%mod; tree[pos<<1|1].mul = (tree[pos<<1|1].mul * tree[pos].mul)%mod; tree[pos<<1|1].lazy = (tree[pos<<1|1].lazy * tree[pos].mul) % mod; for(int i = 1; i < 4; i++) tree[pos<<1|1].sum[i] = (tree[pos<<1|1].sum[i] * (long long)pow(tree[pos].mul,i))%mod; tree[pos].mul = 1; } if(tree[pos].lazy) { int l = tree[pos<<1].l,r = tree[pos<<1].r; long long add = tree[pos].lazy; tree[pos<<1].lazy = (tree[pos<<1].lazy + tree[pos].lazy)%mod; tree[pos<<1].sum[3] = (tree[pos<<1].sum[3]+3*tree[pos<<1].sum[1]*add*add+3*tree[pos<<1].sum[2]*add+(long long)(r-l+1)*add*add*add)%mod; tree[pos<<1].sum[2] = (tree[pos<<1].sum[2]+2*tree[pos<<1].sum[1]*add+(long long)(r-l+1)*add*add)%mod; tree[pos<<1].sum[1] = (tree[pos<<1].sum[1]+(long long)(r-l+1)*add)%mod; l = tree[pos<<1|1].l,r = tree[pos<<1|1].r; tree[pos<<1|1].lazy = (tree[pos<<1|1].lazy + tree[pos].lazy)%mod; tree[pos<<1|1].sum[3] = (tree[pos<<1|1].sum[3]+3*tree[pos<<1|1].sum[1]*add*add+3*tree[pos<<1|1].sum[2]*add+(long long)(r-l+1)*add*add*add)%mod; tree[pos<<1|1].sum[2] = (tree[pos<<1|1].sum[2]+2*tree[pos<<1|1].sum[1]*add+(long long)(r-l+1)*add*add)%mod; tree[pos<<1|1].sum[1] = (tree[pos<<1|1].sum[1]+(long long)(r-l+1)*add)%mod; tree[pos].lazy = 0; }}void build(int l,int r,int pos){ tree[pos].l = l; tree[pos].r = r; for(int i = 0; i < 4; i++) tree[pos].sum[i] = 0; tree[pos].lazy = 0; tree[pos].mul = 1; tree[pos].cover = -1; if(l == r) { //scanf("%lld",&tree[pos].sum); //tree[pos].Max = tree[pos].sum;// tree[pos].Min = tree[pos].sum; return; } int mid = (l+r)/2; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); //pushup(pos);} //建树 //查询操作void update(int l,int r,int pos,long long add,int choose){ add %= mod; if(choose == 1) { if(tree[pos].l == l && tree[pos].r == r) { //tree[pos].sum += (r-l+1)*add; //tree[pos].Max = add;// tree[pos].Min += add; tree[pos].sum[3] = (tree[pos].sum[3]+3*tree[pos].sum[1]*add*add+3*tree[pos].sum[2]*add+(long long)(r-l+1)*add*add*add)%mod; tree[pos].sum[2] = (tree[pos].sum[2]+2*tree[pos].sum[1]*add+(long long)(r-l+1)*add*add)%mod; tree[pos].sum[1] = (tree[pos].sum[1]+(long long)(r-l+1)*add)%mod; tree[pos].lazy += add; tree[pos].lazy %= mod; return; } pushdown(pos); int mid = (tree[pos].l + tree[pos].r) >> 1; if(r <= mid) update(l,r,pos<<1,add,choose); else if(l > mid) update(l,r,pos<<1|1,add,choose); else if(l <= mid && r > mid) { update(l,mid,pos<<1,add,choose); update(mid+1,r,pos<<1|1,add,choose); } pushup(pos); } else if(choose == 2) { if(tree[pos].l == l && tree[pos].r == r) { for(int i = 1; i < 4; i++) tree[pos].sum[i] = (tree[pos].sum[i] * (long long)pow(add,i))%mod; //tree[pos].Max = add; //tree[pos].Min += add; tree[pos].mul = tree[pos].mul * add % mod; tree[pos].lazy = tree[pos].lazy * add % mod; return; } pushdown(pos); int mid = (tree[pos].l + tree[pos].r) >> 1; if(r <= mid) update(l,r,pos<<1,add,choose); else if(l > mid) update(l,r,pos<<1|1,add,choose); else if(l <= mid && r > mid) { update(l,mid,pos<<1,add,choose); update(mid+1,r,pos<<1|1,add,choose); } pushup(pos); } else { if(tree[pos].l == l && tree[pos].r == r) { for(int i = 1; i < 4; i++) tree[pos].sum[i] = (long long)(r-l+1)*(long long)pow(add,i) % mod; //tree[pos].Max = add; //tree[pos].Min += add; tree[pos].lazy = 0; tree[pos].mul = 1; tree[pos].cover = add; return; } pushdown(pos); int mid = (tree[pos].l + tree[pos].r) >> 1; if(r <= mid) update(l,r,pos<<1,add,choose); else if(l > mid) update(l,r,pos<<1|1,add,choose); else if(l <= mid && r > mid) { update(l,mid,pos<<1,add,choose); update(mid+1,r,pos<<1|1,add,choose); } pushup(pos); }} //自上而下更新节点long long query(int l,int r,int pos,int choose){ if(tree[pos].l == l && tree[pos].r == r) return tree[pos].sum[choose]; pushdown(pos); int mid = (tree[pos].l+tree[pos].r)>>1; if(r <= mid) return query(l,r,pos<<1,choose); else if(l > mid) return query(l,r,pos<<1|1,choose); else return (query(l,mid,pos<<1,choose) + query(mid+1,r,pos<<1|1,choose))%mod;}int main(){ int t,n,m,C = 1,num = 0; //scanf("%d",&t); //freopen("1.txt","r",stdin); while(scanf("%d%d",&n,&m) && (n+m)) { build(1,n,1); //printf("Case %d:\n",C++); while(m--) { int k,x,y,c; scanf("%d%d%d%d",&k,&x,&y,&c); if(k == 4) //a[num++] = query(x,y,1,c)%mod; printf("%lld\n",query(x,y,1,c)%mod); else update(x,y,1,(long long)c,k); } }// freopen("2.txt","r",stdin);// long long l;// for(int i = 0; i < num; i++)// {// scanf("%lld",&l);// if(l != a[i])// printf("%d %d %lld %lld\n",i,b[i],l,a[i]);// } return 0;}
- Hdu 4578 Transformation(细节很重要) ★
- hdu 4578 Transformation(线段树)
- HDU 4578-Transformation(线段树)
- HDU - 4578 -Transformation(线段树)
- HDU 4578 Transformation (线段树)
- hdu 4578 Transformation
- hdu 4578 Transformation
- HDU 4578 Transformation
- hdu 4578 Transformation
- HDU-4578-Transformation
- hdu 4578 Transformation
- hdu 4578 Transformation
- hdu 4578 Transformation
- HDU 4578 Transformation
- 细节很重要!
- 细节很重要!
- 细节很重要
- hdu 4578——Transformation
- 基于sklearn 的one hot encoding
- Spring Boot学习记录(三)--整合Mybatis
- tar: Old option 'f' requires an argument.问题解决
- Eclipse 配置Tomcat
- HDU-5821-Ball(贪心)
- Hdu 4578 Transformation(细节很重要) ★
- 打印100~200 之间的素数
- 分布式系统的事务处理
- SDL多线程显示更新窗口
- android的消息机制 handler looper MessageQueue 关系详解
- 安装tensorflow
- Mac 中的sublime text3 如何安装插件
- Leetcode - Bit minipulation - 371. Sum of Two Integers(递归模拟位运算求和)
- table滚动时固定首行