CodeVS4919 线段树练习4
题目链接:http://codevs.cn/problem/4919/
题目描述 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
对于每个询问输出一行一个答案
一道水题。把区间内除以7余0,1,2,3,4,5,6的数的个数都记录下来,更新时维护一下就好了。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define rep(i,l,r) for(int i = l; i <= r; i++) 6 #define clr(x,y) memset(x,y,sizeof(x)) 7 using namespace std; 8 const int INF = 0x3f3f3f3f; 9 const int maxn = 100010; 10 inline int read(){ 11 int ans = 0, f = 1; char c = getchar(); 12 for(; !isdigit(c); c = getchar()) if (c == '-') f = -1; 13 for(; isdigit(c); c = getchar()) ans = ans * 10 + c - '0'; 14 return ans * f; 15 } 16 struct Node{ 17 int l,r,mod[7],f; 18 }t[maxn<<2]; 19 int s[maxn],tmp[7],a,b,x,n,m; 20 char c[10]; 21 inline void change(int w,int p){ 22 rep(i,0,6) tmp[(i+p)%7] = t[w].mod[i]; 23 rep(i,0,6) t[w].mod[i] = tmp[i]; 24 } 25 inline void maintain(int w){ 26 rep(i,0,6) t[w].mod[i] = t[w<<1].mod[i] + t[w<<1|1].mod[i]; 27 } 28 inline void pushdown(int w){ 29 if (t[w].l == t[w].r || (!t[w].f)) return; 30 t[w<<1].f += t[w].f; t[w<<1|1].f += t[w].f; 31 change(w<<1,t[w].f); change(w<<1|1,t[w].f); t[w].f = 0; 32 } 33 void build(int u,int v,int w){ 34 t[w].l = u; t[w].r = v; t[w].f = 0; 35 rep(i,0,6) t[w].mod[i] = 0; 36 if (u == v){ 37 t[w].mod[s[u]%7] = 1; 38 return; 39 } 40 int mid = (u + v) >> 1; 41 build(u,mid,w<<1); build(mid+1,v,w<<1|1); 42 maintain(w); 43 } 44 void modify(int u,int v,int w){ 45 pushdown(w); 46 if (t[w].l == u && t[w].r == v){ 47 t[w].f += x; change(w,x); return; 48 } 49 int mid = (t[w].l + t[w].r) >> 1; 50 if (v <= mid) modify(u,v,w<<1); 51 else if (u > mid) modify(u,v,w<<1|1); 52 else{ 53 modify(u,mid,w<<1); 54 modify(mid+1,v,w<<1|1); 55 } 56 maintain(w); 57 } 58 int query(int u,int v,int w){ 59 pushdown(w); 60 if (t[w].l == u && t[w].r == v) return t[w].mod[0]; 61 int mid = (t[w].l + t[w].r) >> 1; 62 if (v <= mid) return query(u,v,w<<1); 63 else if (u > mid) return query(u,v,w<<1|1); 64 else return query(u,mid,w<<1) + query(mid+1,v,w<<1|1); 65 } 66 int main(){ 67 n = read(); rep(i,1,n) s[i] = read(); 68 build(1,n,1); 69 m = read(); rep(i,1,m){ 70 scanf("%s",c); 71 if (c[0] == 'a'){ 72 a = read(); b = read(); x = read(); 73 modify(a,b,1); 74 } 75 else{ 76 a = read(); b = read(); 77 printf("%d\n",query(a,b,1)); 78 } 79 } 80 return 0; 81 }