codevs 4919 线段树练习4
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
给你N个数,有两种操作
1:给区间[a,b]内的所有数都增加X
2:询问区间[a,b]能被7整除的个数
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是add,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是count,表示统计区间[a,b]能被7整除的个数
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3 2 3 4 6 count 1 3 count 1 2 add 1 3 2 count 1 3 add 1 3 3 count 1 3
样例输出 Sample Output
0
0
0
1
数据范围及提示 Data Size & Hint
10%:1<N<=10,1<Q<=10
30%:1<N<=10000,1<Q<=10000
100%:1<N<=100000,1<Q<=100000
用节点的余数来统计被整除的个数
修改节点的值时 建立临时数组存取统计的个数
然后交换过来
#include <cstdio> #define Max 100000 struct node { int l,r,flag,num[8]; }tr[Max<<2|1]; int n,m,a; void up(int k) { for(int i=0;i<=6;i++) tr[k].num[i]=tr[k<<1].num[i]+tr[k<<1|1].num[i]; } void read(int &x) { x=0;bool f=1; char ch=getchar(); while(ch>'9'||ch<'0') { if(ch=='-') f=0; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+(int)ch-48; ch=getchar(); } x=f?x:(~x)+1; } void build(int k,int l,int r) { tr[k].l=l;tr[k].r=r; if(l==r) { read(a); tr[k].num[a%7]++; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); up(k); } void pushdown(int k) { if(tr[k].l==tr[k].r) return; int tmp[8]; tr[k<<1].flag+=tr[k].flag; tr[k<<1|1].flag+=tr[k].flag; for(int i=0;i<=6;i++) tmp[i]=tr[k<<1].num[i]; for(int i=0;i<=6;i++) { tr[k<<1].num[(i+tr[k].flag)%7]=tmp[i]; tmp[i]=tr[k<<1|1].num[i]; } for(int i=0;i<=6;i++) tr[k<<1|1].num[(i+tr[k].flag)%7]=tmp[i]; tr[k].flag=0; } int section_query(int k,int l,int r) { if(tr[k].l==l&&tr[k].r==r) return tr[k].num[0]; if(tr[k].flag) pushdown(k); int mid=(tr[k].l+tr[k].r)>>1; if(l>mid) return section_query(k<<1|1,l,r); else if(r<=mid) return section_query(k<<1,l,r); else return section_query(k<<1,l,mid)+section_query(k<<1|1,mid+1,r); } void section_change(int k,int l,int r,int v) { if(tr[k].l==l&&tr[k].r==r) { int tmp[8]; for(int i=0;i<=6;i++) tmp[i]=tr[k].num[i]; for(int i=0;i<=6;i++) tr[k].num[(i+v)%7]=tmp[i]; tr[k].flag+=v; return; } if(tr[k].flag) pushdown(k); int mid=(tr[k].l+tr[k].r)>>1; if(l>mid) section_change(k<<1|1,l,r,v); else if(r<=mid) section_change(k<<1,l,r,v); else section_change(k<<1,l,mid,v),section_change(k<<1|1,mid+1,r,v); up(k); } int main() { read(n); build(1,1,n); read(m); char str[11]; for(int x,y,z;m--;) { scanf("%s",str+1); if(str[1]=='c') { read(x);read(y); printf("%d\n",section_query(1,x,y)); } else if(str[1]=='a') { read(x);read(y);read(z); section_change(1,x,y,z); } } return 0; }
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。