codevs4919 线段树练习4
题目描述 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
分类标签 Tags 点此展开
记录好%7的剩余系
暴力统计即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define ls k<<1 7 #define rs k<<1|1 8 using namespace std; 9 const int MAXN=2000050; 10 const int INF=0x7fffffff; 11 void read(int &n) 12 { 13 char c='+';int x=0;bool flag=0; 14 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} 15 while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();} 16 flag==1?n=-x:n=x; 17 } 18 struct node 19 { 20 int l,r,f,mod[7];// mod7的余数的个数 21 }tree[MAXN]; 22 int ans=0; 23 int p[7]; 24 inline void update(int k) 25 { 26 for(int i=0;i<7;i++) tree[k].mod[i]=tree[ls].mod[i]+tree[rs].mod[i]; 27 } 28 int down(int k) 29 { 30 for(int i=0;i<7;i++) p[ (i+tree[k].f)%7 ]=tree[ls].mod[i]; 31 for(int i=0;i<7;i++) tree[ls].mod[i]=p[i]; 32 for(int i=0;i<7;i++) p[ (i+tree[k].f)%7 ]=tree[rs].mod[i]; 33 for(int i=0;i<7;i++) tree[rs].mod[i]=p[i]; 34 tree[ls].f=tree[k].f;tree[rs].f=tree[k].f; 35 tree[k].f=0; 36 } 37 void Build_Tree(int k,int ll,int rr) 38 { 39 tree[k].l=ll;tree[k].r=rr; 40 if(tree[k].l==tree[k].r) 41 { 42 int p;read(p); 43 ++tree[k].mod[p%7]; 44 return ; 45 } 46 if(tree[k].f) down(k); 47 int mid=tree[k].l+tree[k].r>>1; 48 Build_Tree(ls,ll,mid); Build_Tree(rs,mid+1,rr); 49 update(k); 50 } 51 void Interval_Count(int k,int ll,int rr) 52 { 53 if(ll<=tree[k].l&&tree[k].r<=rr) 54 { 55 ans+=tree[k].mod[0]; 56 return ; 57 } 58 if(tree[k].f) down(k); 59 int mid=tree[k].l+tree[k].r>>1; 60 if(ll<=mid) Interval_Count(ls,ll,rr); 61 if(rr>mid) Interval_Count(rs,ll,rr); 62 } 63 void Interval_Add(int k,int ll,int rr,int val) 64 { 65 if(ll<=tree[k].l&&tree[k].r<=rr) 66 { 67 for(int i=0;i<7;i++) p[ (i+val)%7 ]=tree[k].mod[i]; 68 for(int i=0;i<7;i++) tree[k].mod[i]=p[i]; 69 tree[k].f=val; 70 return ; 71 } 72 if(tree[k].f) down(k); 73 int mid=tree[k].l+tree[k].r>>1; 74 if(ll<=mid) Interval_Add(ls,ll,rr,val); 75 if(rr>mid) Interval_Add(rs,ll,rr,val); 76 update(k); 77 } 78 int main() 79 { 80 int n,m; 81 read(n); 82 Build_Tree(1,1,n); 83 read(m); 84 for(int i=1;i<=m;i++) 85 { 86 char s[10]; 87 scanf("%s",s); 88 if(s[0]=='c')//统计能被7整除的数的个数 89 { 90 int x,y;read(x);read(y);ans=0; 91 Interval_Count(1,x,y); 92 printf("%d\n",ans); 93 } 94 else 95 { 96 int x,y,val;read(x);read(y);read(val); 97 Interval_Add(1,x,y,val); 98 } 99 } 100 return 0; 101 }
作者:自为风月马前卒
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。