莫队-作业(题名就是作业)

作业这道题,先不说题面,一看时间限制10000ms每个测试点,然后就出现了一系列的机惨行为,首先是机房最后一排集体交作业,导致评测机负载过大,同时卡了10个评测,然后,一天后也就是今天,我刚一看体,就想到一个$ O(n*m*log(n)) $的暴力,所以自己竟然鼓起勇气交了,但是,第一遍交没有删除freopen,导致200000ms打满,然后在我发现之后又删掉叫了一个,总共两个程序卡了5分钟!(我在这里接受你们的谴责,只要别打脸,别踢裆,咋都行)

然后,说正解!

这道题是莫队和分快的巧妙结合,其实树状数组也可以进行工作,但是经过本人缜(che)密(dan)的分(y)析(y),发现分快的复杂度会低,所以果断使用分快,使用分快维护答案,因为莫队就是分快的思想所以这个莫对和分快很好的结合,其实就是一道水题,我也相信这篇3分钟打的博客也没人看,我主要就是纪念一下这次的机惨

我错了!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 #define debug(x) cout<<x<<" debug!"<<endl;
 8 using namespace std;
 9 const int L=1<<20|1;
10 char buffer[L],*S,*T;
11 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
12 int n,m,pos[3000000],cnt[3000000],blk,s[3000000],g[3000000],ll[3000000],rr[3000000],f[3000000];
13 struct mo{
14 int l,r,res1,res2,id,a,b;
15 }G[3000000];
16 inline int read()
17 {
18     int ss=0;char bb=getchar();
19     while(bb<48||bb>57)bb=getchar();
20     while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
21     return ss;
22 }
23 bool cmp(mo a,mo b){return pos[a.l]==pos[b.l]?a.r<b.r:a.l<b.l;}
24 bool co(mo a,mo b){return a.id<b.id;}
25 void add(int x)
26 {
27     ++f[pos[x]];
28     ++cnt[x];
29     if(cnt[x]==1)g[pos[x]]++;
30 }
31 void rmo(int x)
32 {
33     --f[pos[x]];
34     --cnt[x];
35     if(!cnt[x])g[pos[x]]--;
36 }
37 void make(int l,int r,int x)
38 {
39     if(pos[l]==pos[r])
40     {
41         for(int i=l;i<=r;i++)
42             if(cnt[i])
43                 G[x].res1+=cnt[i],G[x].res2++;
44     }
45     else
46     {
47         for(int i=l;i<=rr[pos[l]];i++)if(cnt[i])G[x].res1+=cnt[i],G[x].res2++;
48         for(int i=ll[pos[r]];i<=r;i++)if(cnt[i])G[x].res1+=cnt[i],G[x].res2++;
49         for(int i=pos[l]+1;i<=pos[r]-1;i++)G[x].res1+=f[i],G[x].res2+=g[i];
50     }
51 }
52 int main()
53 {
54     //freopen("re.cpp","r",stdin);
55     n=read(),m=read();
56     blk=sqrt(n)+1;
57     //debug(blk);
58     int ccp=0;
59     for(int i=1;i<=n;i++)
60     {
61         if(i%blk==1)++ccp,ll[ccp]=i;
62         pos[i]=ccp;
63         //debug(123);
64         if(i%blk==0)rr[ccp]=i;
65     }
66     /*debug(456);
67     for(int i=1;i<=n;i++)
68         printf("%d ",pos[i]);
69     puts("");*/
70     for(int i=1;i<=n;i++)
71         s[i]=read();
72     for(int i=1;i<=m;i++)
73         G[i].l=read(),G[i].r=read(),G[i].a=read(),G[i].b=read(),G[i].id=i;
74     sort(G+1,G+m+1,cmp);
75     int l=1,r=0;
76     for(int i=1;i<=m;i++)
77     {
78         while(l>G[i].l) add(s[--l]);
79         while(l<G[i].l) rmo(s[l++]);
80         while(r<G[i].r) add(s[++r]);
81         while(r>G[i].r) rmo(s[r--]);
82         make(G[i].a,G[i].b,i);
83     }
84     sort(G+1,G+m+1,co);
85     for(int i=1;i<=m;i++)
86     {
87         printf("%d %d\n",G[i].res1,G[i].res2);
88     }
89     return 0;
90 }
View Code

自带卡常优化!

posted @ 2019-07-26 17:27  hzoi_lsc  阅读(148)  评论(0编辑  收藏  举报