HDU 4902 Nice boat (线段树)
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 (线段树)的更多相关文章
- HDU 4902 Nice boat --线段树(区间更新)
题意:给一个数字序列,第一类操作是将[l,r]内的数全赋为x ,第二类操作是将[l,r]中大于x的数赋为该数与x的gcd,若干操作后输出整个序列. 解法: 本题线段树要维护的最重要的东西就是一个区间内 ...
- hdu 4902 Nice boat 线段树
题目链接 给n个数, 两种操作, 第一种是将区间内的数变成x, 第二种是将区间内大于x的数变为gcd(x, a[i]). 开三个数组, 一个记录区间最大值, 这样可以判断是否更新这一区间, 一个laz ...
- HDU 4902 Nice boat 线段树+离线
据说暴力也过了.还傻逼地写了这么长. . . #include <stdio.h> #include <string.h> #include <math.h> #i ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...
- 线段树 + 区间更新 ----- HDU 4902 : Nice boat
Nice boat Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- 2014多校第四场1006 || HDU 4902 Nice boat (线段树 区间更新)
题目链接 题意 : 给你n个初值,然后进行两种操作,第一种操作是将(L,R)这一区间上所有的数变成x,第二种操作是将(L,R)这一区间上所有大于x的数a[i]变成gcd(x,a[i]).输出最后n个数 ...
- HDU 5091---Beam Cannon(线段树+扫描线)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...
随机推荐
- Vim的可视模式
可视模式可以看到选中的字符串, 并对其进行操作 v:进入字符选择模式 V:进入行选择模式 ctrl-v(Window是ctrl-q):进入block选择模式 o:移动光标到选择的另一端 O:移动光标到 ...
- [Codeforces673A]Bear and Game(水题,思路)
题目链接:http://codeforces.com/contest/673/problem/A 题意:一个人看一个90分钟的节目,然后告诉你一些有趣的时刻.这个人假如在15分钟内还没有看到有趣的时刻 ...
- 使用easyui实现列表的批量删除
使用easyui实现列表的批量删除 首先要做的就是增加一个多选框 <table id="otGrid" nowrap="false" style=&quo ...
- org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xml
org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xml at org.hibernate ...
- hMailserver设置外部反病毒扫描程序
刚在5dmail上发现有人提出一个问题,他在hmailserver的外部病毒扫描程序中使用了瑞星那个娱乐货,结果呢,说瑞星太勇猛了,所有附件都认为病毒了,这是怎么个情况呢? 先从hmailadmin里 ...
- UVa 12716 (GCD == XOR) GCD XOR
题意: 问整数n以内,有多少对整数a.b满足(1≤b≤a)且gcd(a, b) = xor(a, b) 分析: gcd和xor看起来风马牛不相及的运算,居然有一个比较"神奇"的结论 ...
- BZOJ 2179 FFT快速傅里叶
fft. #include<set> #include<map> #include<ctime> #include<queue> #include< ...
- php通过curl调用jpush接口实现消息的推送
public function actionNotifyto() { //$regid = $_REQUEST['regid']; $url = 'https://api.jpush.cn/v3/pu ...
- objective-c里的方法指针IMP的用法
SGPopSelectView.h @interface SGPopSelectView : UIView @property (nonatomic, assign) SEL selector; @p ...
- HDU 1213 How Many Tables (并查集,常规)
并查集基本知识看:http://blog.csdn.net/dellaserss/article/details/7724401 题意:假设一张桌子可坐无限多人,小明准备邀请一些朋友来,所有有关系的朋 ...