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 ...
随机推荐
- OVS常用命令
添加brideg: sudo ovs-vsctl add-br br0 删除brideg: sudo ovs-vsctl del-br br0 显示bridge: sudo ovs-vsctl sho ...
- zookeeper 启动失败 BindException: Address already in use 或者Error contacting service. It is probably not running
平台:centos-6.3-i386 jdk-7u51 storm 0.9.1 python 2.6.6 hadoop 1.2.1 今天上午装storm的时候遇到这个问题,好郁闷.把网上介绍的方法 ...
- bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图
http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...
- JAVA_SE基础——31.this关键字
黑马程序员入学blog... 也算是学习笔记体会. this的通俗解释: 有一个A类,一个B方法,一个C变量,其中B和C都在类A中 this.B()就是调用A类中的B方法 this.C=1(假设C是一 ...
- xxe漏洞检测及代码执行过程
这两天看了xxe漏洞,写一下自己的理解,xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目録遍历等.首先存在漏洞的web服务一定是存 ...
- C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现
我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...
- LeetCode & Q219-Contains Duplicate II
Array Hash Table Description: Given an array of integers and an integer k, find out whether there ar ...
- js正则表达语法
/* *通过量词可以设置一个内容出现的次数 *量词只对它前边的一个内容起作用.所以在作用多个时需要用小括号()来向计算机说明这是一个整体. *-{n}代表正好出现n次. *-{m,n}出现了m-n次. ...
- 新概念英语(1-105)Full Of Mistakes
Lesson 105 Full of mistakes 错误百出 Listen to the tape then answer this question. What was Sandra's pre ...
- SLF4J - 借助SLF4J, 统一适配所有日志实现为logback日志实现的实践
一.屏蔽各种日志实现,去掉各种日志实现的实现依赖 二.引入slf4j和各种日志实现的适配器 1.引入slf4j 2.引入各种日志实现的适配器(适配到slf4j) 3.引入logback 引入logba ...