Nice boat

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4902

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=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


##题意:

对一个数组进行若干操作后,输出结果数组.
1. 将区间内的值都变为x.
2. 将区间内的大于x的值ai变为gcd(ai,x).


##题解:

很容易想到用线段树维护,关键是如何操作2的gcd.
对于树中的每个结点维护一个equal, 表示当前结点的子节点是否相等. (若相等就等于子节点的值,否则为-1).
当更新到某区间时,若区间内的值都相同,则只更新到这里即可,下面的结点利用pushdown来更新.


##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define eps 1e-8
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;

LL gcd(LL a, LL b) {

return !b? a:gcd(b, a%b);

}

int n;

LL num[maxn];

struct Tree

{

int left,right;

LL lazy, equl;

}tree[maxn<<2];

void build(int i,int left,int right)

{

tree[i].left=left;

tree[i].right=right;

tree[i].lazy=0;

if(left==right){
tree[i].equl = num[left];
return ;
} int mid=mid(left,right); build(i<<1,left,mid);
build(i<<1|1,mid+1,right); tree[i].equl = tree[i<<1].equl==tree[i<<1|1].equl ? tree[i<<1].equl : -1;

}

void pushdown(int i)

{

if(tree[i].equl != -1) {

tree[i<<1].equl = tree[i].equl;

tree[i<<1|1].equl = tree[i].equl;

tree[i].lazy = 0;

tree[i<<1].lazy = 0;

tree[i<<1|1].lazy = 0;

}

if(tree[i].lazy) {

tree[i<<1].lazy = tree[i].lazy;

tree[i<<1|1].lazy = tree[i].lazy;

if(tree[i<<1].equl != -1) {

tree[i<<1].equl = tree[i].lazy;

tree[i<<1].lazy = 0;

}

if(tree[i<<1|1].equl != -1) {

tree[i<<1|1].equl = tree[i].lazy;

tree[i<<1|1].lazy = 0;

}

tree[i].lazy = 0;

}

}

void update(int i,int left,int right,LL d)

{

if(tree[i].leftleft&&tree[i].rightright)

{

if(tree[i].equl == -1) tree[i].lazy = d;

else tree[i].equl = d;

return ;

}

pushdown(i);

int mid=mid(tree[i].left,tree[i].right);

if(right<=mid) update(i<<1,left,right,d);
else if(left>mid) update(i<<1|1,left,right,d);
else {
update(i<<1,left,mid,d);
update(i<<1|1,mid+1,right,d);
} tree[i].equl = tree[i<<1].equl==tree[i<<1|1].equl ? tree[i<<1].equl : -1;

}

void update_gcd(int i,int left,int right, LL x)

{

if(tree[i].leftleft&&tree[i].rightright && tree[i].equl!=-1)

{

if(tree[i].equl > x) {

tree[i].equl = gcd(tree[i].equl, x);

tree[i].lazy = 0;

}

return ;

}

pushdown(i);

int mid=mid(tree[i].left,tree[i].right);

if(right<=mid) update_gcd(i<<1,left,right,x);
else if(left>mid) update_gcd(i<<1|1,left,right,x);
else {
update_gcd(i<<1,left,mid,x);
update_gcd(i<<1|1,mid+1,right,x);
} tree[i].equl = tree[i<<1].equl==tree[i<<1|1].equl ? tree[i<<1].equl : -1;

}

LL query(int i,int left,int right)

{

if(tree[i].leftleft&&tree[i].rightright)

return tree[i].equl;

pushdown(i);

int mid=mid(tree[i].left,tree[i].right);

if(right<=mid) return query(i<<1,left,right);
else if(left>mid) return query(i<<1|1,left,right);
else return query(i<<1,left,mid)+query(i<<1|1,mid+1,right);

}

int main(int argc, char const *argv[])

{

//IN;

int t; cin >> t;
while(t--)
{
int m;
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%lld", &num[i]);
build(1, 1, n); scanf("%d", &m);
while(m--) {
int op, l, r; LL x;
scanf("%d %d %d %lld", &op,&l,&r,&x);
if(op == 1) {
update(1, l, r, x);
}
else if(op == 2) {
update_gcd(1, l, r, x);
}
} for(int i=1; i<=n; i++) {
printf("%lld ", query(1, i, i));
}
printf("\n");
} return 0;

}

HDU 4902 Nice boat (线段树)的更多相关文章

  1. HDU 4902 Nice boat --线段树(区间更新)

    题意:给一个数字序列,第一类操作是将[l,r]内的数全赋为x ,第二类操作是将[l,r]中大于x的数赋为该数与x的gcd,若干操作后输出整个序列. 解法: 本题线段树要维护的最重要的东西就是一个区间内 ...

  2. hdu 4902 Nice boat 线段树

    题目链接 给n个数, 两种操作, 第一种是将区间内的数变成x, 第二种是将区间内大于x的数变为gcd(x, a[i]). 开三个数组, 一个记录区间最大值, 这样可以判断是否更新这一区间, 一个laz ...

  3. HDU 4902 Nice boat 线段树+离线

    据说暴力也过了.还傻逼地写了这么长. . . #include <stdio.h> #include <string.h> #include <math.h> #i ...

  4. hdu 5700区间交(线段树)

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  5. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  6. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  7. 线段树 + 区间更新 ----- HDU 4902 : Nice boat

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

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

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

  9. HDU 5091---Beam Cannon(线段树+扫描线)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...

随机推荐

  1. android4.4内核移植

    01 init/目录下Kconfig修改: 956行添加: config PANIC_TIMEOUT int "Default panic timeout" help Set de ...

  2. xmlsechema验证

                   //创建xmlDocument                 XmlDocument doc = new XmlDocument();                  ...

  3. 自定义View(6)paint设置图图层重叠时的显示方式,包含清空canvas

    Paint.setXfermode 这个函数设置两个图层相交时的模式 在已有的图层上绘图将会在其上面添加一层新的图层. 如果新的图层是完全不透明的,那么它将完全遮挡住下面的图层,而setXfermod ...

  4. ConcurrentDictionary和Dictionary

    http://stackoverflow.com/questions/6739193/is-the-concurrentdictionary-thread-safe-to-the-point-that ...

  5. Oracle过程包加密

    Oracle加绕功能可以将PL/SQL代码实现部分隐藏,如存储过程.函数.包体等均可使用加绕功能,下面以一个存储过程实现部分加绕来展示Oracle加绕功能的使用.  加绕方法一: 1.编写如下存储过程 ...

  6. Android Touch事件分发机制

    参考:http://blog.csdn.net/xiaanming/article/details/21696315 参考:http://blog.csdn.net/wangjinyu501/arti ...

  7. gulp 使用mailgun服务器发送邮件

    1.首先你需要创建一个 mailgun 账户,没有请去注册一个. 注册之后会有 mailgun 会给你一个默认的子域名,你就可以使用这个子域名去发送邮件了,如下图: 2.gulp创建任务: var s ...

  8. POJ 3211 (分组01背包) Washing Clothes

    题意: 小明有一个贤妻良母型的女朋友,他们两个一起洗衣服. 有M种颜色的N件衣服,要求洗完一种颜色的衣服才能洗另外一种颜色. 两人可以同时洗,一件衣服只能被一个人洗. 给出洗每件衣服所用的时间,求两个 ...

  9. BZOJ3105: [cqoi2013]新Nim游戏

    题解: 线性基?类似于向量上的基底. 此题题解戳这里:http://blog.csdn.net/wyfcyx_forever/article/details/39477673 代码: #include ...

  10. C扩展Python - official docs - defining new type

    1. Code & Official_doc: THIS 2. My question. #include <Python.h> /* * 1.PyTypeObject doc, ...