codevs4919 线段树练习4

时间:2022-05-08
本文章向大家介绍codevs4919 线段树练习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的剩余系

暴力统计即可

  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("%dn",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 }