http://acm.hdu.edu.cn/showproblem.php?pid=4902
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
16807 937186357 937186357 937186357 937186357 1 1 1624379149 1624379149 1624379149
连着两场多校比赛出现了线段树的题目,这是下半年亚洲赛要出题的节奏吗?哈哈~~~
解题思路:够造线段树,每个顶点包含两个值,一个flag作为标记的标志,另一个value做为节点的存储值,如果该节点左右子节点的值是相同的那么我们就把该节点的值也赋为它,若不相同就把其值赋为-1.标记2时只标记到子节点相同的点为止。
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const int maxn=110005; int a[maxn]; struct SegementTree { struct Tree { int l,r; int flag; int value; } tree[maxn*4]; int __gcd(int x,int y) { if(y==0) return x; return __gcd(y,x%y); } void push_up(int root) { if(tree[root<<1|1].value==tree[root<<1].value) tree[root].value=tree[root<<1].value; else tree[root].value=-1; } void push_down(int root) { if(tree[root].flag!=-1) { tree[root<<1].flag=tree[root<<1|1].flag=tree[root].flag; tree[root<<1].value=tree[root<<1|1].value=tree[root].flag; tree[root].flag=-1; } } void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; tree[root].flag=-1; if(l==r) { tree[root].value=a[r]; return; } int mid=l+(r-l)/2; build(root<<1,l,mid); build(root<<1|1,mid+1,r); push_up(root); } void update1(int root,int l,int r,int x)//更改为某个值 { if(l<=tree[root].l&&tree[root].r<=r) { tree[root].flag=tree[root].value=x; return; } push_down(root); int mid=tree[root].l+(tree[root].r-tree[root].l)/2; if(l<=mid) update1(root<<1,l,r,x); if(mid<r) update1(root<<1|1,l,r,x); push_up(root); } void update2(int root,int l,int r,int x)//变为gcd(); { if(tree[root].value!=-1&&l<=tree[root].l&&tree[root].r<=r) { if(tree[root].value>x) { // printf("(%d %d)\n",x,__gcd(x,tree[root].value)); tree[root].flag=tree[root].value=__gcd(tree[root].value,x); } return; } push_down(root); int mid=tree[root].l+(tree[root].r-tree[root].l)/2; if(l<=mid) update2(root<<1,l,r,x); if(mid<r) update2(root<<1|1,l,r,x); push_up(root); } void query(int root) { if(tree[root].l==tree[root].r) { a[tree[root].l]=tree[root].value; return; } push_down(root); query(root<<1); query(root<<1|1); } } tr; int main() { int n,T,m; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); tr.build(1,1,n); scanf("%d",&m); while(m--) { int p,x,y,z; scanf("%d%d%d%d",&p,&x,&y,&z); if(p==1) { tr.update1(1,x,y,z); } else if(p==2) { tr.update2(1,x,y,z); } } tr.query(1); for(int i=1; i<=n; i++) printf(i==n?"%d \n":"%d ",a[i]); } return 0; }