洛谷模拟赛 数据结构
题目背景
引言
数据结构学的好,未来工作没烦恼。
Edgration 是一个喜欢乱搞数据结构的蒟蒻(以下简称edt),有一天,他作死想去***难一下dalao:
edt想求一种数据结构,使得可以实现区间加,求出某一区间大于k的元素的个数
dalao1:sb线段树
dalao2:sb分块
dalao3:sb平衡树
edt: 不行,那就加上取模,求区间取膜mod后大于MIN小于MAX的元素个数
dalao1:线段树&……¥#&……%……&*&%¥
dalao2:sb分块 &%¥……%#¥#&……&*
dalao3:*&……%&¥LCT维护SBT水题 &……%&……%
edt:那不仅取模,每个数乘上数组下标再取模
dalao:¥%¥¥&*(#¥% 叽里呱啦叽里呱啦
edt:不行,在把取模的值丢到一棵树上,维护一棵仙人掌乘积方差的最小极差
dalao:替罪羊树上用sb块状链表维护Toptree上的最小费用最大流和可持久化仙人掌,算出来在基尔霍夫矩阵中反演后跑一遍fft维护的插头DP就好了,给我三分钟轻松水过。。
edt:mmp
题目描述
蒟蒻Edt把这个问题交给了你 ———— 一个精通数据结构的大犇,由于是第一题,这个题没那么难。。
edt 现在对于题目进行了如下的简化:
最开始的数组每个元素都是0
给出nn,optopt,modmod,minmin,maxmax,modmod在int范围内
操作AA,QQ
AA: LL,RR,XX 表示把[l,R][l,R]这个区间加上XX
(数组的从L到R的每个元素都加上X)
QQ: LL,RR 表示询问[L,R][L,R]这个区间中元素T满足 min<=(T*imin<=(T∗i%mod)<=maxmod)<=max 的 T这样的数的个数(i是数组下标)
(元素的值*数组下标%mod在min到max范围内)
由于 edt 请来了一位非三次元的仓鼠,他帮你用延后了部分问题,将这些询问打入了混乱时空,你的询问操作不会超过1000次,不幸的是,对于延后的询问操作可能有很多次(小于1e7次),但是保证这些延后的询问操作之后不会再次有修改操作
(就是在最后会有很多次询问,但不会进行修改)
输入输出格式
输入格式:
给出n,opt,mod,min,max表示序列大小,操作次数,取膜,最小值,最大值
下面opt行,给出
AA: LL,RR,XX表示区间加,保证X在int范围内(<2147483647)
QQ:LL,RR表示区间查询满足条件的个数
再给出一个FinalFinal值,表示后面有FinalFinal个询问
下面FinalFinal行,给出
LL,RR表示询问区间[L,R][L,R]表示询问[L,R][L,R]之间满足条件的个数
输出格式:
每行对于每个QQ操作输出QQ个数表示每次询问的值,
下面FinalFinal行表示FinalFinal个询问的值
输入输出样例
17 25 4098 310 2622 A 10 16 657212040 A 4 15 229489140 A 1 2 -433239891 A 3 12 532385784 A 10 17 56266644 A 8 10 10038874 A 6 9 13084764 A 4 5 -9206340 Q 2 8 A 2 4 -43223955 A 6 9 31478706 A 2 4 189818310 A 2 8 179421180 A 2 8 40354938 Q 8 14 A 3 6 57229575 A 6 13 132795740 A 2 17 14558022 A 14 15 -552674185 A 5 11 -1104138 Q 2 12 Q 1 14 A 3 9 524902182 A 8 12 114291440 A 3 7 107531442 1 11 12
3 6 7 8 2
20 3 4317 1020 2232 A 8 15 -434078222 A 1 2 54988154 A 13 19 81757858 15 7 11 3 5 3 9 6 9 9 13 6 19 1 20 3 5 3 10 1 7 2 14 6 10 2 3 2 3 10 12
0 0 0 0 0 2 2 0 0 0 0 0 0 0 0
说明
样例说明
给出样例1的解释:
样例1中,aa数组修改为55,55,55
每个a[i]*ia[i]∗i%44 的值为11,22,33
对于Final的询问
询问[1[1,3]3]中大于等于0小于等于2的个数为2个
剩下的询问类似
题目说明
注意:
1.关于负数取模问题,请以 c++ 的向0取整为标准,即如:
[ -7−7%3 = -13=−1 ] [ 77%3 = 13=1 ]
2.一共会有50个测试点,每个点分值为2分。
因为测试点数较多,请oier们自觉地不要故意多次提交来卡评测机,出题人 edt 在这里表示由衷的感谢
数据范围
如果你不能作对所有点,请尝试获得部分分,所有数据都是随机生成
不要往数据结构方面想,其实是一道简单的暴力题
我们发现,在前面的操作中,询问很少,大多是修改
后面很多操作都是询问
也就是说,只要后面做到O(1)询问
前面O(1)修改,O(1~n)询问就行了
修改直接差分数组,查询时加一遍O(n)来判断
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long lol; 7 lol n,q,Mod,Min,Max,a[100001],sum[100001]; 8 char s[101]; 9 lol l,r,now,ans; 10 int main() 11 {lol x,i; 12 cin>>n>>q>>Mod>>Min>>Max; 13 while (q--) 14 { 15 scanf("%s %lld%lld",s,&l,&r); 16 if (s[0]=='A') 17 { 18 scanf("%lld",&x); 19 a[l]+=x;a[r+1]-=x; 20 } 21 else 22 { 23 now=0,ans=0; 24 for (i=1;i<=r;i++) 25 { 26 now+=a[i]; 27 if (i>=l&&(now*i)%Mod>=Min&&(now*i)%Mod<=Max) ans++; 28 } 29 printf("%d\n",ans); 30 } 31 } 32 now=0; 33 for (i=1;i<=n;i++) 34 { 35 now+=a[i]; 36 if ((now*i)%Mod>=Min&&(now*i)%Mod<=Max) sum[i]=1; 37 else sum[i]=0; 38 sum[i]+=sum[i-1]; 39 } 40 cin>>q; 41 while (q--) 42 { 43 scanf("%lld%lld",&l,&r); 44 printf("%lld\n",sum[r]-sum[l-1]); 45 } 46 }