題目傳送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
差分多用於優化離線的區間修改。
前綴和多用於離線的區間查詢。