# BZOJ 3236: [Ahoi2013]作业

## 3236: [Ahoi2013]作业

Time Limit: 100 Sec  Memory Limit: 512 MB
Submit: 732  Solved: 271

3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3

2 2
1 1
3 2
2 1

## HINT

N=100000,M=1000000

## Source

### 代码

  1 /*Author:WNJXYK*/
2 #include<cstdio>
3 #include<algorithm>
4 using namespace std;
5
6 const int Maxm=1000000;
7 struct QuestionNode{
8     int l,r;
9     int a,b;
10     int index;
11 };
12 QuestionNode quest[Maxm+10];
13 struct AnsNode{
14     int Ans1,Ans2;
15 };
16 AnsNode ans[Maxm+10];
17
18 const int Maxn=100000;
19 int cnt[Maxn+10];
20
21 int siz;
22 int n,m;
23 int num[Maxn+10];
24
25 int sum1[Maxn+10],sum2[Maxn+10],cot[Maxn+10];
26
27 inline int remin(int a,int b){
28     if (a<b) return a;
29     return b;
30 }
31
32 inline bool cmp(QuestionNode a,QuestionNode b){
33     if (cnt[a.l]<cnt[b.l]) return true;
34     if (cnt[a.l]==cnt[b.l] && a.r<b.r) return true;
35     return false;
36 }
37
38 inline int lowbit(int x){
39     return x&-x;
40 }
41
42 inline void add(int c[],int x,int num){
43     for (int i=x;i<=Maxn;i+=lowbit(i))c[i]+=num;
44 }
45
46 inline int get(int c[],int x){
47     int res=0;
48     for (int i=x;i;i-=lowbit(i))res+=c[i];
49     return res;
50 }
51
52 int main(){
53     scanf("%d%d",&n,&m);
54     //GetCnt
55     while(siz*siz<n) siz++;
56     for (int i=1;i<=siz;i++){
57         int st=siz*(i-1)+1,ed=(remin(siz*i,n));
58         for (int j=st;j<=ed;j++){
59             cnt[j]=i;
60         }
61     }
62     //GetNum
63     for (int i=1;i<=n;i++) scanf("%d",&num[i]);
64     //GetQuest
65     for (int i=1;i<=m;i++)scanf("%d%d%d%d",&quest[i].l,&quest[i].r,&quest[i].a,&quest[i].b);
66     for (int i=1;i<=m;i++)quest[i].index=i;
67     //SortQuest
68     sort(quest+1,quest+m+1,cmp);
69     //GetAns
70     int left=1,right=0;
71     for (int i=1;i<=m;i++){
72         int l=quest[i].l,r=quest[i].r;
73         int a=quest[i].a,b=quest[i].b;
74         int index=quest[i].index;
75         while (left<l){
76             cot[num[left]]--;
79             left++;
80         }
81         while(l<left){
82             left--;
83             cot[num[left]]++;
86         }
87         while(right<r){
88             right++;
89             cot[num[right]]++;
92         }
93         while(r<right){
94             cot[num[right]]--;
97             right--;
98         }
99         ans[index].Ans1=get(sum1,b)-get(sum1,a-1);
100         ans[index].Ans2=get(sum2,b)-get(sum2,a-1);
101     }
102     //Print
103     for (int i=1;i<=m;i++) printf("%d %d\n",ans[i].Ans1,ans[i].Ans2);
104     return 0;
105 }
View Code

posted @ 2014-11-30 21:20  WNJXYK  阅读(264)  评论(0编辑  收藏  举报