hdu 4578 线段树(标记处理)
Transformation
Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 4095 Accepted Submission(s): 1008
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.
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.
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
/*
hdu 4578 线段树(标记处理) 给你n个初始化为0的数进行以下操作:
1 x y c 给[x,y]上的数全加上c add
2 x y c 给[x,y]上的数全乘上c mult
3 x y c 将[x,y]上面的数全置为c same
4 x y c 查询[x,y]上所有数的c次方的和,然后对10007取模 首先我们可以发现 加法和乘法都无法直接维护我们想要的到的立方和,但对于same而言
sum = (r-l+1)*(tree[i].same^p).
如果每次查询我们都查找到单点,有极大的可能TLE。所以考虑查询的时候直接查找same标记,而且p也很小。
然后就是如何处理add,mult,same这三个标记的冲突.
就是same而言,更新到一个区间,那么先前这个区间上的所有标记都会作废
对于add和mult很明显会冲突,到后面你并不能知道是先处理add还是mult.所以
add和mult不能同时共处一个区间,而且先前到达的标记要先更新下去. 于是对于add和mult分3种情况: //就add而言
1.如果当前区间有same,那愉快地更新same就好了
2.如果当前区间有mult,那先对当前区间进行update_down,把mult标记先更新下去
3.如果只有add这个标记,那么更新一下即可 感觉就标记下放这方面,主要是注意标记相互之间的影响。
hhh-2016-04-04 09:41:07
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef long long ll;
const int mod = 10007;
const int maxn = 100050;
struct node
{
int l,r;
ll mult,add,same;
int mid()
{
return (l+r)>>1;
}
int len()
{
return (r-l+1) ;
}
} tree[maxn<<2]; void update_up(int i)
{
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
tree[i].mult=1;
tree[i].add=0;
tree[i].same = -1;
if(l == r)
{
tree[i].same = 0;
return ;
}
build(lson,l,tree[i].mid());
build(rson,tree[i].mid()+1,r);
update_up(i);
} void update_down(int i)
{
if(tree[i].same != -1)
{
tree[lson].add = tree[rson].add = 0;
tree[lson].mult= tree[rson].mult = 1;
tree[lson].same = tree[rson].same = tree[i].same;
tree[i].same = -1;
}
if(tree[i].add)
{
if(tree[lson].same != -1)
tree[lson].same = (tree[lson].same+tree[i].add)%mod;
else if(tree[lson].mult > 1)
{
update_down(lson);
tree[lson].add = tree[i].add;
}
else
tree[lson].add = (tree[lson].add+tree[i].add)%mod;
if(tree[rson].same != -1)
tree[rson].same = (tree[rson].same+tree[i].add)%mod;
else if(tree[rson].mult > 1)
{
update_down(rson);
tree[rson].add = tree[i].add;
}
else
tree[rson].add = (tree[rson].add+tree[i].add)%mod;
tree[i].add = 0;
}
if(tree[i].mult > 1)
{
if(tree[lson].same != -1)
tree[lson].same = (tree[lson].same*tree[i].mult)%mod;
else if(tree[lson].add)
{
update_down(lson);
tree[lson].mult = tree[i].mult;
}
else
tree[lson].mult = (tree[lson].mult*tree[i].mult)%mod;
if(tree[rson].same != -1)
tree[rson].same = (tree[rson].same*tree[i].mult)%mod;
else if(tree[rson].add)
{
update_down(rson);
tree[rson].mult = tree[i].mult;
}
else
tree[rson].mult = (tree[rson].mult*tree[i].mult)%mod;
tree[i].mult = 1;
}
} void update(int i,int l,int r,int flag,ll val)
{
if(tree[i].l >= l && tree[i].r <= r)
{
if(flag == 1)
{
if(tree[i].same != -1)
tree[i].same = (tree[i].same+val)%mod;
else if(tree[i].mult > 1)
{
update_down(i);
tree[i].add = val;
}
else
tree[i].add =(tree[i].add+val)%mod;
}
else if(flag == 2)
{
if(tree[i].same != -1)
tree[i].same = (tree[i].same*val)%mod;
else if(tree[i].add)
{
update_down(i);
tree[i].mult = val;
}
else
tree[i].mult = (tree[i].mult * val) %mod;
}
else if(flag == 3)
{
tree[i].same = val;
tree[i].same %= mod;
tree[i].add = 0;
tree[i].mult = 1;
}
return ;
}
int mid = tree[i].mid();
update_down(i);
if(l <= mid)
update(lson,l,r,flag,val);
if(r > mid)
update(rson,l,r,flag,val);
update_up(i);
} ll query(int i,int l,int r,int p)
{
if(tree[i].l == tree[i].r)
{
ll ans = 1;
for(int j =1; j <= p; j++)
ans =(ll)(ans*tree[i].same)%mod;
return ans%mod;
}
if(tree[i].l >= l && tree[i].r <= r && tree[i].same != -1)
{
ll ans = 1;
for(int j =1; j <= p; j++)
ans =(ll)(ans*tree[i].same)%mod;
ans = (ll)ans*(tree[i].len()%mod)%mod;
return ans%mod;
}
ll all = 0;
update_down(i);
int mid = tree[i].mid();
if(l <= mid)
all =(all+query(lson,l,r,p))%mod;
if(r > mid)
all = (all+query(rson,l,r,p))%mod;
return all;
} int main()
{
int t,n,m;
while(scanf("%d%d",&n,&m) && n && m)
{
build(1,1,n);
for(int i = 1; i <= m; i++)
{
int op,x,y;
ll c;
scanf("%d%d%d%I64d",&op,&x,&y,&c);
if(op <= 3)
update(1,x,y,op,c);
else
printf("%I64d\n",query(1,x,y,c));
}
}
return 0;
}
hdu 4578 线段树(标记处理)的更多相关文章
- hdu 3954 线段树 (标记)
Level up Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HDU 4578 线段树玄学算法?
Transformation 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is p ...
- K - Transformation HDU - 4578 线段树经典题(好题)
题意:区间 加 变成定值 乘 区间查询:和 平方和 立方和 思路:超级超级超级麻烦的一道题 设3个Lazy 标记分别为 change 改变mul乘 add加 优先度change>m ...
- HDU 4578 线段树复杂题
题目大意: 题意:有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部乘c. 3:区间[l,r]内的数全部初始为c. 4:询问区间[l,r]内所有数的P次方之和. ...
- HDU - 4578 线段树+三重操作
这道题自己写了很久,还是没写出来,也看了很多题解,感觉多数还是看的迷迷糊糊,最后面看到一篇大佬的才感觉恍然大悟. 先上一篇大佬的题解:https://blog.csdn.net/aqa20372995 ...
- hdu 4578 线段树 ****
链接:点我 1
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 2871 线段树(各种操作)
Memory Control Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 4267 线段树间隔更新
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
随机推荐
- python 之反射
通过字符串的形式导入模块 通过字符串的形式,去模块中寻找制定的函数,并执行getattr(模块名,函数名,默认值) 通过字符串的形式,去模块中设置东西setattr(模块名,函数名/变量名,lambd ...
- java 注解的实现机制
一.什么是注解: 注解是标记,也可以理解成是一种应用在类.方法.参数.属性.构造器上的特殊修饰符.注解作用有以下三种: 第一种:生成文档,常用的有@param@return等. 第二种:替代配置文件的 ...
- 第五章 JavaScript对象及初识面向对象
第五章 JavaScript对象及初识面向对象 一.对象 在JavaScript中,所有事物都是对象,如字符串.数值.数组.函数等. 在JavaScript对象分为内置对象和自定义对象,要处理一些 ...
- 单点登录实现机制:桌面sso
参考链接,感谢作者:https://zm10.sm-tc.cn/?src=l4uLj8XQ0IiIiNGckZ2TkJiM0ZyQktCZlo2Mi5uNmp6S0I/QysrJyszPztGXi5K ...
- eclipse开发Groovy代码,与java集成,maven打包编译
今天尝试了一下在eclipse里面写Groovy代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来. 首先需要给eclipse安装一下Groovy的插件,插件地址:https://gith ...
- 由路由器AP隔离引起的WEB服务不能访问的问题
最近在自己的电脑上运行了一个Web服务,发现它只能被本机访问,无法在同一个局域网的其它设备访问. 于是在网上搜索了各种资料,通通都是在操作系统层面来分析解决问题的. 而我怎么尝试都不成功的情况下,差点 ...
- hdu 1880 魔咒字典
https://vjudge.net/problem/HDU-1880 题意:略 思路: 一开始就是想到了正确的思路,但是代码写炸了,死活过不了.这题嘛,就是建议一个魔咒与咒语的双向映射.首先用字符串 ...
- oracle:批量插入不同方案对比
实时测试的速度: --48466条数据 --1.297 inline view更新法 inline view更新法就是更新一个临时建立的视图 update (select a.join_stateas ...
- Java-Maven(七):Eclipse中Maven依赖、聚合、继承特性
之前通过学习了解,maven集成到eclipse中的如何创建项目,以及maven命令插件在eclipse中安装后的用法.那么接下来我们将会学习一些maven在项目中的一些特性,及如何使用. Maven ...
- vue-cli 的项目 切换到Linux环境下遇到问题
之前用vue-cli脚手架在windows上开发的一个项目,现在有换mac的打算,但是换系统的话对代码对环境依赖比较严重. 去年和别的FE并行开发两个人用的都是windows,这样还好,没有什么问题, ...