[CF877F]Ann and Books

题目大意:
  有$n(n\le10^5)$个数$w_{1\sim n}(|w_i|\le10^9)$,并给定一个数$k(|k|\le10^9)$。$q(q\le10^5)$次询问,每次询问区间$[l,r]$中满足数字之和等于$k$的子区间数。

思路:
  莫队卡常。

 1 #pragma GCC optimize("Ofast")
 2 #pragma GCC optimize("unroll-loops")
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cctype>
 6 #include<algorithm>
 7 #include<unordered_map>
 8 #include<tr1/unordered_map>
 9 using int64=long long;
10 inline int getint() {
11     register char ch;
12     register bool neg=false;
13     while(!isdigit(ch=getchar())) neg|=ch=='-';
14     register int x=ch^'0';
15     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
16     return neg?-x:x;
17 }
18 constexpr int N=1e5+1,M=1e5;
19 int k,block;
20 int64 a[N],ans[N],tmp;
21 struct Query {
22     int l,r,id;
23     bool operator < (const Query &another) const {
24         return l/block==another.l/block?r<another.r:l/block<another.l/block;
25     }
26 };
27 Query q[M];
28 std::tr1::unordered_map<int64,int> map;
29 inline void ins(const int64 &x,const bool &b) {
30     tmp+=map[x-k*(b?1:-1)];
31     map[x]++;
32 }
33 inline void del(const int64 &x,const bool &b) {
34     map[x]--;
35     tmp-=map[x-k*(b?1:-1)];
36 }
37 int main() {
38     const int n=getint();
39     block=sqrt(n)*2,k=getint();
40     for(register int i=1;i<=n;i++) {
41         a[i]=getint()==1?1:-1;
42     }
43     for(register int i=1;i<=n;i++) {
44         (a[i]*=getint())+=a[i-1];
45     }
46     const int m=getint();
47     for(register int i=0;i<m;i++) {
48         const int l=getint()-1,r=getint();
49         q[i]={l,r,i};
50     }
51     std::sort(&q[0],&q[m]);
52     for(register int i=0,l=0,r=-1;i<m;i++) {
53         while(l>q[i].l) ins(a[--l],0);
54         while(r<q[i].r) ins(a[++r],1);
55         while(l<q[i].l) del(a[l++],0);
56         while(r>q[i].r) del(a[r--],1);
57         ans[q[i].id]=tmp;
58     }
59     for(register int i=0;i<m;i++) {
60         printf("%I64d%c",ans[i]," \n"[i==m-1]);
61     }
62     return 0;
63 }

 

posted @ 2018-05-04 16:42  skylee03  阅读(223)  评论(0编辑  收藏  举报