题目传送ios
感受这道题秀了我一地的智商。。。git
审题没审好,没肯定带修改的操做中询问的次数<=1000,且max和min都是事先给好、不变的。想了半天线段树、分块,却忘了最基础的暴力。优化
写不出题时先写暴力。spa
先考虑在线的部分的作法:code
由于修改的次数多,询问的次数少,并且询问很难在在线的状况下优化了,又发现数据随机,若是询问暴力处理的话最差复杂度也只有O(1000*n),在随机数据下复杂度远比此低。因而能够用差分优化区间加,询问暴力作就行。blog
离线部分:get
显然不能暴力处理询问了,可是没有修改,又是区间询问个数,天然要想到前缀和优化了。设sum[i]为前i位知足条件的个数,扫一遍就能处理出sum,这是就能O(1)作询问了。it
代码:io
1 #include<iostream>
2 #include<cstdio>
3
4 using namespace std; 5
6 const int N=80005; 7
8 int n,opt,minn,maxx,fin,X; 9 int x,sum[N]; 10
11 long long d[N],now,t,mod; 12
13 char ch; 14
15 bool f; 16
17 inline int read() 18 { 19 x=0; 20 f=0; 21 ch=getchar(); 22 while(!isdigit(ch)) f|=(ch=='-'),ch=getchar(); 23 while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); 24 return f?-x:x; 25 } 26
27 inline char mygetchar() 28 { 29 ch=getchar(); 30 while(ch!='A'&&ch!='Q') 31 ch=getchar(); 32 return ch; 33 } 34
35 void print(int a) 36 { 37 if(a>9) 38 print(a/10); 39 putchar(a%10+'0'); 40 } 41
42 int main() 43 { 44 // freopen("my.out","w",stdout);
45 n=read(),opt=read(),mod=read(),minn=read(),maxx=read(); 46 char cao; 47 int l,r; 48 for(int i=1;i<=opt;++i) 49 { 50 cao=mygetchar(); 51 if(cao=='A') 52 { 53 l=read(),r=read(),X=read(); 54 d[l]+=X; 55 d[r+1]-=X; 56 } 57 else
58 { 59 l=read(),r=read(); 60 int ans=0,j; 61 now=0; 62 for(j=1;j<l;++j) 63 now+=d[j]; 64 for(j=l;j<=r;++j) 65 { 66 now+=d[j]; 67 t=now%mod*j%mod; 68 if(t>=minn&&t<=maxx) 69 ans++; 70 } 71 print(ans); 72 putchar('\n'); 73 } 74 } 75 fin=read(); 76 now=0; 77 for(int i=1;i<=n;++i) 78 { 79 now+=d[i]; 80 t=now%mod*i%mod; 81 sum[i]=sum[i-1]+(t>=minn&t<=maxx); 82 } 83 for(int i=1;i<=fin;++i) 84 { 85 l=read(),r=read(); 86 print(sum[r]-sum[l-1]); 87 putchar('\n'); 88 } 89 return 0; 90 }
总结:写不出题想一想暴力(没准就是正解呢)class
差分多用于优化离线的区间修改。
前缀和多用于离线的区间查询。