码迷,mamicode.com
首页 > 其他好文 > 详细

4919 线段树练习4

时间:2016-08-23 21:47:50      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

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

分类标签 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\n",query(1,x,y+1));
        }
    }
    return 0;
}

 

4919 线段树练习4

标签:

原文地址:http://www.cnblogs.com/shenben/p/5800796.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!