zoukankan      html  css  js  c++  java
  • BZOJ 3236 作业

    莫队+值域分块。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 100050
    #define maxm 1000050
    using namespace std;
    int n,m,a[maxn],ans[maxm][3],pos[maxn],ret=316,st[maxn],tot=0;
    int cnt[maxn][5];
    struct query
    {
        int l,r,a,b,id;
    }q[maxm];
    bool cmp(const query &x,const query &y)
    {
        if (pos[x.l]!=pos[y.l]) return pos[x.l]<pos[y.l];
        else return x.r<y.r;
    }
    int read()
    {
        char ch;int data=0;
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9')
        {
            data=data*10+ch-'0';
            ch=getchar();
        }
        return data;
    }
    void build()
    {
        tot=1;
        for (int i=1;i<=n;i++)
        {
            pos[i]=tot;
            if (!(i%ret)) st[tot++]=i;
        }
        if (n%ret) st[tot]=n;else tot--;
    }
    void modify(int x,int val)
    {
        int base=cnt[x][1];
        cnt[x][1]+=val;cnt[pos[x]][2]+=val;
        if ((cnt[x][1]==0) && (base==1)) {cnt[x][3]--;cnt[pos[x]][4]--;}
        if ((cnt[x][1]==1) && (base==0)) {cnt[x][3]++;cnt[pos[x]][4]++;}
    }
    void ask(int l,int r,int x)
    {
        int ret1=0,ret2=0;
        if (pos[l]==pos[r])
        {
            for (int i=l;i<=r;i++)
                ret1+=cnt[i][1],ret2+=cnt[i][3];
        }
        else
        {
            for (int i=l;i<=st[pos[l]];i++) ret1+=cnt[i][1],ret2+=cnt[i][3];
            for (int i=st[pos[r]-1]+1;i<=r;i++) ret1+=cnt[i][1],ret2+=cnt[i][3];
            for (int i=pos[l]+1;i<=pos[r]-1;i++) ret1+=cnt[i][2],ret2+=cnt[i][4];
        }
        ans[q[x].id][1]=ret1;ans[q[x].id][2]=ret2;
    }
    int main()
    {
        n=read();m=read();
        for (int i=1;i<=n;i++) a[i]=read();
        for (int i=1;i<=m;i++)
        {
            q[i].l=read();q[i].r=read();q[i].a=read();q[i].b=read();
            q[i].id=i;
        }
        build();sort(q+1,q+m+1,cmp);
        int l=1,r=0;
        for (int i=1;i<=m;i++)
        {
            for (;r<q[i].r;r++) modify(a[r+1],1);
            for (;r>q[i].r;r--) modify(a[r],-1);
            for (;l<q[i].l;l++) modify(a[l],-1);
            for (;l>q[i].l;l--) modify(a[l-1],1);
            ask(q[i].a,q[i].b,i);
        }
        for (int i=1;i<=m;i++) printf("%d %d
    ",ans[i][1],ans[i][2]);
        return 0;
    }
  • 相关阅读:
    获取office版本
    SQL中判断字符串中包含字符的方法
    wpf 多表头
    webservice MaxReceivedMessageSize :已超过传入消息(65536)的最大消息大小配额
    QQ检测登陆及QQ协议
    ssl-openssl简介
    抓包及分析(wireshark&tcpdump)
    Git的一些东西(后续补充)
    SSH实现隧道功能穿墙
    Nmap参考指南(Man Page)
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6590273.html
Copyright © 2011-2022 走看看