BZOJ 3809 莫队+(分块|BIT)

Posted on 2016-05-27 15:09  yyjxx2010xyu  阅读(99)  评论(0编辑  收藏  举报
 1  
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #include <cmath>
 9 #define pa pair<int,int>
10 #define mp make_pair
11 #define fi first
12 #define se second
13 #define pb push_back
14 using namespace std;
15 inline void Get_Int(int &x)
16 {
17     x=0;  char ch=getchar(); int f=1;
18     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
19     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
20 }
21 inline void Put_Int(int x)
22 {
23     char ch[20]; int top=0;
24     if (x==0) ch[++top]='0';
25     while (x) ch[++top]=x%10+'0',x/=10;
26     while (top) putchar(ch[top--]); putchar('\n');
27 }
28 //===================================================
29 const int Maxn=101000;
30 const int Maxm=1010000;
31 struct Node{int l,r,u,v,id;}q[Maxm];
32  
33 int n,m,s[Maxn],Block,Ans[Maxm],b[Maxn],B[Maxn];//Ans开Maxm
34 inline int Get(int x) {return (x-1)/Block+1;}
35 inline int Query(int x,int y)
36 {
37     int l=Get(x),r=Get(y),ret=0;
38     if (l==r)
39     {
40         for (int i=x;i<=y;i++) if (b[i]) ret++;
41         return ret;
42     } 
43     for (int i=l+1;i<r;i++) ret+=B[i];
44     for (int i=x;Get(i)==l;i++) if (b[i]) ret++;
45     for (int i=y;Get(i)==r;i--) if (b[i]) ret++;
46     return ret;
47 }
48 inline bool cmp(Node A,Node B) 
49 {
50     if (Get(A.l)==Get(B.l)) return A.r<B.r;
51     return Get(A.l)<Get(B.l);
52 }
53 inline void Del(int x) 
54 {if (b[s[x]]==1) B[Get(s[x])]--; b[s[x]]--;}
55 inline void Add(int x) 
56 {if (b[s[x]]==0) B[Get(s[x])]++; b[s[x]]++;}
57  
58 int main()
59 {
60     Get_Int(n),Get_Int(m); Block=(int)sqrt(n);
61     for (int i=1;i<=n;i++) Get_Int(s[i]);
62     for (int i=1;i<=m;i++) 
63         Get_Int(q[i].l),Get_Int(q[i].r),Get_Int(q[i].u),Get_Int(q[i].v),q[i].id=i;
64     memset(b,0,sizeof(b));
65     memset(B,0,sizeof(B));
66     sort(q+1,q+m+1,cmp);
67     int L=1,R=0;
68      
69     for (int i=1;i<=m;i++)
70     {
71         while (R<q[i].r) R++,Add(R);
72         while (L>q[i].l) L--,Add(L);
73         while (L<q[i].l) Del(L),L++;
74         while (R>q[i].r) Del(R),R--;
75         Ans[q[i].id]=Query(q[i].u,q[i].v);
76     }
77     for (int i=1;i<=m;i++) Put_Int(Ans[i]);
78     return 0;
79 }
分块 40s
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <vector>
 7 #include <cmath>
 8 #define pa pair<int,int>
 9 #define mp make_pair
10 #define fi first
11 #define se second
12 #define pb push_back
13 using namespace std;
14 inline void Get_Int(int &x)
15 {
16     x=0;  char ch=getchar(); int f=1;
17     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
18     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
19 }
20 inline void Put_Int(int x)
21 {
22     char ch[20]; int top=0;
23     if (x==0) ch[++top]='0';
24     while (x) ch[++top]=x%10+'0',x/=10;
25     while (top) putchar(ch[top--]); putchar('\n');
26 }
27 //===================================================
28 const int Maxn=101000;
29 const int Maxm=1010000;
30 struct Node{int l,r,u,v,id;}q[Maxm];
31  
32 int c[Maxn],n,m,s[Maxn],Block,Ans[Maxm],b[Maxn];//Ans开Maxm
33 inline int lowbit(int x) {return x&(-x);}
34 inline int Query(int x)
35 {int ret=0; for (int i=x;i;i-=lowbit(i)) ret+=c[i];return ret;}
36 inline void Modify(int x,int v)
37 {for (int i=x;i<=n;i+=lowbit(i)) c[i]+=v;}
38 inline int Get(int x) {return (x-1)/Block+1;}
39 inline bool cmp(Node A,Node B) 
40 {
41     if (Get(A.l)==Get(B.l)) return A.r<B.r;
42     return Get(A.l)<Get(B.l);
43 }
44 inline void Del(int x) 
45 {if (b[s[x]]==1) Modify(s[x],-1);b[s[x]]--;}
46 inline void Add(int x) 
47 {if (b[s[x]]==0) Modify(s[x],1); b[s[x]]++;}
48  
49 int main()
50 {
51     Get_Int(n),Get_Int(m); Block=(int)sqrt(n/2);
52     for (int i=1;i<=n;i++) Get_Int(s[i]);
53     for (int i=1;i<=m;i++) 
54         Get_Int(q[i].l),Get_Int(q[i].r),Get_Int(q[i].u),Get_Int(q[i].v),q[i].id=i;
55     memset(b,0,sizeof(b));
56     memset(c,0,sizeof(c));
57     sort(q+1,q+m+1,cmp);
58     int L=1,R=0;
59     for (int i=1;i<=m;i++)
60     {
61         while (R<q[i].r) R++,Add(R);
62         while (L>q[i].l) L--,Add(L);
63         while (L<q[i].l) Del(L),L++;
64         while (R>q[i].r) Del(R),R--;
65         Ans[q[i].id]=Query(q[i].v)-Query(q[i].u-1);
66     }
67     for (int i=1;i<=m;i++) Put_Int(Ans[i]);
68     return 0;
69 }
BIT 77s

对权值分块复杂度更优.