时间限制: 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> #include<cstring> using namespace std; const int N=100010; struct node { int lazy,l,r; int sum[8]; }tr[N<<2]; int arr[10]; inline void pushup(int ro) { for(int i=0;i<=6;i++) tr[ro].sum[i]=tr[ro<<1].sum[i]+tr[ro<<1|1].sum[i]; } void build(int ro,int l,int r) { tr[ro].l=l,tr[ro].r=r; if(l==r) { int a; scanf("%d",&a); tr[ro].sum[a%7]++; } else { int mid=(l+r)>>1; build(ro<<1,l,mid); build(ro<<1|1,mid+1,r); pushup(ro); } return; } inline void down(int ro) { tr[ro<<1].lazy+=tr[ro].lazy; tr[ro<<1|1].lazy+=tr[ro].lazy; for(int i=0;i<=6;i++) arr[i]=0,arr[i]=tr[ro<<1].sum[i]; for(int i=0;i<=6;i++) tr[ro<<1].sum[(i+tr[ro].lazy)%7]=arr[i]; for(int i=0;i<=6;i++) arr[i]=0,arr[i]=tr[ro<<1|1].sum[i]; for(int i=0;i<=6;i++) tr[ro<<1|1].sum[(i+tr[ro].lazy)%7]=arr[i]; tr[ro].lazy=0; } void change(int ro,int l,int r,int add) { if(l<=tr[ro].l&&tr[ro].r<=r) { for(int i=0;i<=6;i++) arr[i]=0,arr[i]=tr[ro].sum[i]; for(int i=0;i<=6;i++) tr[ro].sum[(i+add)%7]=arr[i]; //printf("%d\n",add); tr[ro].lazy+=add; tr[ro].lazy%=7; //for(int i=1;i<=20;i++) {for(int j=0;j<=6;j++) printf("%d ",tr[i].sum[j]);printf("%d %d\n",tr[i].l,tr[i].r);} return; } if(tr[ro].lazy) down(ro); int mid=(tr[ro].l+tr[ro].r)>>1; if(l<=mid) change(ro<<1,l,r,add); if(mid<r) change(ro<<1|1,l,r,add); pushup(ro); return; } long long int query(int ro,int l,int r) { if(l<=tr[ro].l&&tr[ro].r<=r) return tr[ro].sum[0]; if(tr[ro].lazy) down(ro); long long int ans=0; int mid=(tr[ro].l+tr[ro].r)>>1; if(l<=mid) ans+=query(ro<<1,l,r); if(r>mid) ans+=query(ro<<1|1,l,r); return ans; } int main() { int n; scanf("%d",&n); build(1,1,n); //for(int i=1;i<=20;i++) {for(int j=0;j<=6;j++) printf("%d ",tr[i].sum[j]);printf("%d %d\n",tr[i].l,tr[i].r);} int m; scanf("%d",&m); for(int i=1;i<=m;i++) { char pd[8]; scanf("%s",pd); if(pd[0]==‘a‘) { int a,b,x; scanf("%d %d %d",&a,&b,&x); change(1,a,b,x%7); //for(int k=1;k<=20;k++) {for(int j=0;j<=6;j++) printf("%d ",tr[k].sum[j]);printf("%d %d\n",tr[k].l,tr[k].r);} } else { int l,r; scanf("%d %d",&l,&r); printf("%lld\n",query(1,l,r)); } } return 0; }
关键是我们需要维护的东西是什么?
我们用一个数组存区间内%7后每个值的个数;
最后输出值为0的个数。
时间: 2024-11-05 15:47:00