Nice boat

Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 146    Accepted Submission(s): 75

Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil.
Also, this devil is looking like a very cute Loli.

Let us continue our story, z*p(actually you) defeat the 'MengMengDa' party's leader, and the 'MengMengDa' party dissolved. z*p becomes the most famous guy among the princess's knight party.

One day, the people in the party find that z*p has died. As what he has done in the past, people just say 'Oh, what a nice boat' and don't care about why he died.

Since then, many people died but no one knows why and everyone is fine about that. Meanwhile, the devil sends her knight to challenge you with Algorithm contest.

There is a hard data structure problem in the contest:

There are n numbers a_1,a_2,...,a_n on a line, everytime you can change every number in a segment [l,r] into a number x(type 1), or change every number a_i in a segment [l,r] which is bigger than x to gcd(a_i,x) (type 2).

You should output the final sequence.

 
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains a integers n.
The next line contains n integers a_1,a_2,...,a_n separated by a single space.
The next line contains an integer Q, denoting the number of the operations.
The next Q line contains 4 integers t,l,r,x. t denotes the operation type.

T<=2,n,Q<=100000
a_i,x >=0
a_i,x is in the range of int32(C++)

 
Output
For each test case, output a line with n integers separated by a single space representing the final sequence.
Please output a single more space after end of the sequence
 
Sample Input
1
10
16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709
10
1 3 6 74243042
2 4 8 16531729
1 3 4 1474833169
2 1 8 1131570933
2 7 9 1505795335
2 3 7 101929267
1 4 10 1624379149
2 2 8 2110010672
2 6 7 156091745
1 2 5 937186357
 
Sample Output
16807 937186357 937186357 937186357 937186357 1 1 1624379149 1624379149 1624379149
 
Author
WJMZBMR
 

题意:给定一个数字序列,对其进行两种操作:1、将序列中连续的一段变成一样的数x;2、给序列中连续的一段和一个数x,对于这个连续一段中的每个数,如果小于x则取x与这个数的最大公约数,否则不操作。

题解:线段树+懒人标记

代码:

 #include <cstdio>
#include <cstring> const int LEN = ; struct line
{
int left;
int right;
int value;
}line[LEN*];
int point[LEN*]; //记录线段树底层节点的位置 inline int gcd(int a,int b) //求最大公约数
{
return a % b ? gcd(b, a % b) : b;
} void buildt(int left, int right, int step) //建树同时初始化懒惰标记
{
line[step].value = -;
line[step].left = left;
line[step].right = right;
if (left == right){
point[left] = step;
return;
}
int mid = (left + right) / ;
buildt(left, mid, step*);
buildt(mid+, right, step*+);
} void query_1(int left, int right, int x, int step) //操作一
{
if (left == line[step].left && right == line[step].right){
line[step].value = x;
return;
}
if (line[step].value != -){
line[step*].value = line[step*+].value = line[step].value;
line[step].value = -;
}
int mid = (line[step].left + line[step].right) / ;
if (right <= mid)
query_1(left, right, x, step*);
else if (left > mid)
query_1(left, right, x, step*+);
else{
query_1(left, mid, x, step*);
query_1(mid+, right, x, step*+);
}
} void query_2(int left, int right, int x, int step) //操作函数二
{
if (line[step].left == left && line[step].right == right){
if (line[step].value != -){ //如果找到对应区间,且有标记,则进行条件判断,否则继续
if (line[step].value > x)
line[step].value = gcd(line[step].value, x);
return;
}
}
if (line[step].value != -){ //如果改点被标记,则下移一层
line[step*].value = line[step*+].value = line[step].value;
line[step].value = -;
}
int mid = (line[step].left + line[step].right) / ;
if (right <= mid)
query_2(left, right, x, step*);
else if (left > mid)
query_2(left, right, x, step*+);
else{
query_2(left, mid, x, step*);
query_2(mid+, right, x, step*+);
}
} void findans(int left, int right, int step) //dfs输出结果
{
if (line[step].left == left && line[step].right == right){
if (line[step].value != -){
for(int i = ; i < line[step].right - line[step].left + ; i++)
printf("%d ", line[step].value);
return;
}
}
if (line[step].value != -){
line[step*].value = line[step*+].value = line[step].value;
line[step].value = -;
}
int mid = (line[step].left + line[step].right) / ;
if (right <= mid)
findans(left, right, step*);
else if (left > mid)
findans(left, right, step*+);
else{
findans(left, mid, step*);
findans(mid+, right, step*+);
}
} int main()
{
int T;
//freopen("in.txt", "r", stdin);
scanf("%d", &T);
while(T--){
int n;
memset(point, , sizeof(point));
scanf("%d", &n);
buildt(, n, );
for(int i = ; i <= n; i++){
int t;
scanf("%d", &t);
line[point[i]].value = t;
}
int m;
scanf("%d", &m);
for(int i = ; i < m; i++){
int t, l, r, x;
scanf("%d %d %d %d", &t, &l, &r, &x);
if (t == ){
query_1(l, r, x, );
}
else if (t == ){
query_2(l, r, x, );
}
}
findans(, n, );
printf("\n");
}
return ;
}

【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记的更多相关文章

  1. 2014多校第四场1006 || HDU 4902 Nice boat (线段树 区间更新)

    题目链接 题意 : 给你n个初值,然后进行两种操作,第一种操作是将(L,R)这一区间上所有的数变成x,第二种操作是将(L,R)这一区间上所有大于x的数a[i]变成gcd(x,a[i]).输出最后n个数 ...

  2. 2019牛客多校第四场A meeting——树的直径

    题意: 一颗 $n$ 个节点的树上标有 $k$ 个点,找一点使得到 $k$ 个关键结点的最大距离最小. 分析: 问题等价于求树的直径,最小距离即为直径除2向上取整. 有两种求法,一是动态规划,对于每个 ...

  3. hdu6606多校第四次04——线段树加速dp

    /* 首先想到二分答案,难点在于如何判断是否有K段,每段和<=mid 把问题转化成求最多有R段,最少有L段,每段的的和<=mid,如果 L<=K<=R 那么显然存在把这个序列分 ...

  4. 牛客多校第四场 A meeting 树的半径

    题意: 有一棵树,树上有许多人,他们要聚会,找一个点使得所有人到这个点的距离的最大值最小. 题解: 首先,以一个有人的点为根,求一个生成树,删掉所有没有人的子树,保证所有的悬挂点(只连接一条边的点)都 ...

  5. Transformation HDU - 4578(线段树——懒惰标记的妙用)

    Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...

  6. 2018 HDU多校第四场赛后补题

    2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...

  7. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  8. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  9. 牛客多校第3场 J 思维+树状数组+二分

    牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...

随机推荐

  1. scheme Continuation

    Continuation Pass Style在函数式编程(FP)中有一种被称为Continuation Passing Style(CPS)的风格.在这种风格的背后所蕴含的思想就是将处理中可变的一部 ...

  2. 给Visual Studio更替皮肤和背景图

    给Visual Studio更换皮肤和背景图 1.先安装更换皮肤的插件  VS菜单栏里面找到:工具>扩展和更新>联机>搜索: Theme Editor   下载并安装: 安装后先不着 ...

  3. 使用 apache ant 轻松实现文件压缩/解压缩(转)

    原文地址:http://blog.csdn.net/irvine007/article/details/6779492 maven配置ant包: <dependency> <grou ...

  4. One Way Roads(搜索)

    One Way Roads Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit S ...

  5. Winpcap网络编程九之Winpcap实战,ARP协议获得MAC表及主机通信

    大家好,本次我们须要完毕的任务是: 完毕两台主机之间的数据通信(数据链路层) 仿真ARP协议获得网段内主机的MAC表 使用帧完毕两台主机的通信(Hello! I'm -) 声明:本文章的目的是为大家的 ...

  6. c#语句:分支

    六.分支:(一)if (表达式){}说明:1.表达式,就是用来返回bool形的表达式.2.if的小括号后面千万不要加分号 (二)if(表达式){}else{} 例:1.输入年龄,大于等于18显示成年, ...

  7. uploadify按钮中文乱码问题

    uploadify是一款基于jQuery库的上传插件,但很可惜的是无论你怎么设置参数buttonText ,它的中文按钮都会出现乱码的情况,现把出现原因及解决方法总结如下.       那么出现这种的 ...

  8. pl/sql连接远程服务器

    1.oracle提供了instantclient,下载instantclient-basic-win32-10.2.0.4.zip,将包解压存放到本地,如:D:\STUDY\instantclient ...

  9. Hortonworks 用于做 Sentimental Analysis的Hiveddl.sql 文件

    The hiveddl.sql script has performed the following steps to refine the data: Converted the raw Twitt ...

  10. 第二章实例:Android窗口菜单显示

    package test.main.cls; import com.example.popupwindow.R; import android.app.Activity; import android ...