题目描述 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余0,1,2,3,4,5,6的数的个数都记录下来,更新时维护一下就好了
AC代码:
#include<cstdio> using namespace std; #define ll long long #define N 200100 int cnt,tmp[N],a[N]; char s[100]; inline const int read(){ register int x=0,f=1; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct node{ int l,r,lch,rch,tage; int s[7]; }tr[N<<2]; void pushdown(int k,int p){ for(int i=0;i<=6;i++) tmp[(i+p)%7]=tr[k].s[i]; for(int i=0;i<=6;i++) tr[k].s[i]=tmp[i]; } void updata(int k){ pushdown(tr[k].lch,tr[k].tage); pushdown(tr[k].rch,tr[k].tage); tr[tr[k].lch].tage+=tr[k].tage; tr[tr[k].rch].tage+=tr[k].tage; tr[k].tage=0; } void sum(int k){ for(int i=0;i<=6;i++) tr[k].s[i]=tr[tr[k].lch].s[i]+tr[tr[k].rch].s[i]; } void build(int l,int r){ int k=++cnt; tr[cnt].l=l;tr[cnt].r=r; if(l==r-1){ tr[k].s[a[l]]++;return ; } tr[k].lch=cnt+1; int mid=(l+r)>>1; build(l,mid); tr[k].rch=cnt+1; build(mid,r); //tr[k].sum=tr[tr[k].lch].sum+tr[tr[k].rch].sum; sum(k); } void add(int k,int l,int r,int p){ if(l<=tr[k].l&&r>=tr[k].r){ tr[k].tage=(tr[k].tage+p)%7; pushdown(k,p); return ; } if(tr[k].tage) updata(k); int mid=(tr[k].l+tr[k].r>>1); if(l<mid) add(tr[k].lch,l,r,p); if(r>mid) add(tr[k].rch,l,r,p); sum(k); } int query(int k,int l,int r){ if(l<=tr[k].l&&r>=tr[k].r) return tr[k].s[0]; int ans=0; if(tr[k].tage) updata(k); int mid=(tr[k].l+tr[k].r>>1); if(l<mid) ans+=query(tr[k].lch,l,r); if(r>mid) ans+=query(tr[k].rch,l,r); return ans; } int main(){ int n,m,opt,x,y,val; n=read(); for(int i=1;i<=n;i++) a[i]=read()%7; build(1,n+1); m=read(); for(int i=1;i<=m;i++){ scanf("%s",s); if(s[0]=='a'){ x=read();y=read();val=read()%7; add(1,x,y+1,val); } else{ x=read();y=read(); printf("%d ",query(1,x,y+1)); } } return 0; }