zoukankan      html  css  js  c++  java
  • BZOJ3236:[AHOI2013]作业(莫队,分块)

    Description

    Input

    Output

    Sample Input

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

    Sample Output

    2 2
    1 1
    3 2
    2 1

    HINT

    N=100000,M=1000000

    Solution

    首先有一个比较显然的做法就是用莫队加树状数组……然而这样的话复杂度是$nsqrt nlog$。

    因为树状数组的修改和查询都是$log$的,所以我们用一个修改$O(1)$,查询$O(sqrt n)$的分块代替树状数组,那么总的复杂度就是$nsqrt n$了。

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define N (100009)
     7 #define M (1000009)
     8 #define S (359)
     9 using namespace std;
    10 
    11 int n,m,a[N],l,r,x,y,ans2,Keg[N],q_num;
    12 int ID[N],L[S],R[S],Val[N][2],Sum[N][2];
    13 struct Que
    14 {
    15     int l,r,a,b,id,ans1,ans2;
    16     bool operator < (const Que &a) const
    17     {
    18         if (ID[l]==ID[a.l]) return r<a.r;
    19         return ID[l]<ID[a.l];
    20     }
    21 }Q[M];
    22 bool cmp(Que a,Que b) {return a.id<b.id;}
    23 
    24 inline int read()
    25 {
    26     int x=0,w=1; char c=getchar();
    27     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
    28     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
    29     return x*w;
    30 }
    31 
    32 void Build()
    33 {
    34     int unit=sqrt(n);
    35     int num=n/unit+(n%unit!=0);
    36     for (int i=1; i<=num; ++i)
    37         L[i]=(i-1)*unit+1, R[i]=i*unit;
    38     R[num]=n;
    39     for (int i=1; i<=num; ++i)
    40         for (int j=L[i]; j<=R[i]; ++j) ID[j]=i;
    41 }
    42 
    43 int Query(int l,int r,int opt)
    44 {
    45     int ans=0;
    46     if (ID[l]==ID[r])
    47     {
    48         for (int i=l; i<=r; ++i) ans+=Val[i][opt];
    49         return ans;
    50     }
    51     for (int i=l; i<=R[ID[l]]; ++i) ans+=Val[i][opt];
    52     for (int i=L[ID[r]]; i<=r; ++i) ans+=Val[i][opt];
    53     for (int i=ID[l]+1; i<=ID[r]-1; ++i) ans+=Sum[i][opt];
    54     return ans;
    55 }
    56 
    57 void Del(int p)
    58 {
    59     Val[a[p]][0]--; Sum[ID[a[p]]][0]--;
    60     if (!Val[a[p]][0]) Val[a[p]][1]--, Sum[ID[a[p]]][1]--;
    61 }
    62 
    63 void Ins(int p)
    64 {
    65     Val[a[p]][0]++; Sum[ID[a[p]]][0]++;
    66     if (Val[a[p]][0]==1) Val[a[p]][1]++, Sum[ID[a[p]]][1]++;
    67 }
    68 
    69 int main()
    70 {
    71     n=read(); m=read();
    72     Build();
    73     for (int i=1; i<=n; ++i) a[i]=read();
    74     for (int i=1; i<=m; ++i)
    75     {
    76         l=read(); r=read(); x=read(); y=read();
    77         Q[++q_num]=(Que){l,r,x,y,i};
    78     }
    79     sort(Q+1,Q+m+1);
    80     int l=1,r=0;
    81     for (int i=1; i<=m; ++i)
    82     {
    83         while (l<Q[i].l) Del(l++);
    84         while (l>Q[i].l) Ins(--l);
    85         while (r<Q[i].r) Ins(++r);
    86         while (r>Q[i].r) Del(r--);
    87         Q[i].ans1=Query(Q[i].a,Q[i].b,0);
    88         Q[i].ans2=Query(Q[i].a,Q[i].b,1);
    89     }
    90     sort(Q+1,Q+m+1,cmp);
    91     for (int i=1; i<=m; ++i)
    92         printf("%d %d
    ",Q[i].ans1,Q[i].ans2);
    93 }
  • 相关阅读:
    D
    Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals
    Mondriaan's Dream POJ
    Traveling by Stagecoach POJ
    HDU1024_Max Sum Plus Plus
    stl_vector去重方法
    POJ3255次短路模板
    springMVC和spring上下文的关系
    @Resource @Autowired 区别
    XPath语法
  • 原文地址:https://www.cnblogs.com/refun/p/10365714.html
Copyright © 2011-2022 走看看