• loj #2254. 「SNOI2017」一个简单的询问


    #2254. 「SNOI2017」一个简单的询问

    题目描述

    给你一个长度为 NNN 的序列 aia_iai​​,1≤i≤N1leq ileq N1iN,和 qqq 组询问,每组询问读入 l1,r1,l2,r2l_1,r_1,l_2,r_2l1​​,r1​​,l2​​,r2​​,需输出

    ∑x=0∞get(l1,r1,x)⋅get(l2,r2,x) sumlimits_{x=0}^infty ext{get}(l_1,r_1,x)cdot ext{get}(l_2,r_2,x)x=0​​get(l1​​,r1​​,x)get(l2​​,r2​​,x)

    get(l,r,x) ext{get}(l,r,x)get(l,r,x) 表示计算区间 [l,r][l,r][l,r] 中,数字 xxx 出现了多少次。

    输入格式

    第一行,一个数字 NNN,表示序列长度。
    第二行,NNN 个数字,表示 a1∼aNa_1sim a_Na1​​aN​​。
    第三行,一个数字 QQQ,表示询问个数。
    第 4∼Q+34sim Q+34Q+3 行,每行四个数字 l1,r1,l2,r2l_1,r_1,l_2,r_2l1​​,r1​​,l2​​,r2​​,表示询问。

    输出格式

    对于每组询问,输出一行一个数字,表示答案。

    样例

    样例输入

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

    样例输出

    4
    1

    数据范围与提示

    对于 20%20\%20% 的数据,1≤N,Q≤10001leq N,Qleq 10001N,Q1000;
    对于另外 30%30\%30% 的数据,1≤ai≤501leq a_ileq 501ai​​50;
    对于 100%100\%100% 的数据,N,Q≤50000N,Qleq 50000N,Q50000,1≤ai≤N1leq a_ileq N1ai​​N,1≤l1≤r1≤N1leq l_1leq r_1leq N1l1​​r1​​N,1≤l2≤r2≤N1leq l_2leq r_2leq N1l2​​r2​​N。

    数据范围与原题相同,但测试数据由本站会员自制,并非原数据。
    时限已按照评测机速度调整,原题时限为 2000 ms,省选评测时调整为 4000 ms,这里按 4000 ms 调整。

    注意:答案有可能超过 int 的最大值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 50010
    using namespace std;
    int n,a[maxn],b[maxn],l1,r1,l2,r2,mx,cnt[maxn][2],num;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+n+1);
        num=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++)
            a[i]=lower_bound(b+1,b+num+1,a[i])-b;
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            memset(cnt,0,sizeof(cnt));
            for(int i=l1;i<=r1;i++)cnt[a[i]][0]++;
            for(int i=l2;i<=r2;i++)cnt[a[i]][1]++;
            long long ans=0;
            for(int i=1;i<=num;i++)ans+=1LL*cnt[i][0]*cnt[i][1];
            cout<<ans<<endl;
        }
        return 0;
    }
    80分 暴力
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define maxn 50010
    using namespace std;
    int n,block[maxn],sz,a[maxn],num1[maxn],num2[maxn],m,tot,L,R;
    long long res=0,Ans[maxn];
    struct node{
        int l,r,id,ad;
        bool operator < (const node &b)const{
            if(block[l]==block[b.l])return r<b.r;
            return l<b.l;
        }
    }q[maxn*4];
    int main(){
        scanf("%d",&n);sz=sqrt(n);
        for(int i=1;i<=n;i++)block[i]=(i-1)/sz+1;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        scanf("%d",&m);
        int l1,l2,r1,r2;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            q[++tot]=(node){r1,r2,i,1};
            q[++tot]=(node){r1,l2-1,i,-1};
            q[++tot]=(node){l1-1,r2,i,-1};
            q[++tot]=(node){l1-1,l2-1,i,1};
        }
        sort(q+1,q+tot+1);
        for(int i=1;i<=tot;i++){
            while(L<q[i].l)L++,res+=num2[a[L]],++num1[a[L]];
            while(L>q[i].l)res-=num2[a[L]],--num1[a[L]],--L;
            while(R<q[i].r)++R,res+=num1[a[R]],++num2[a[R]];
            while(R>q[i].r)res-=num1[a[R]],--num2[a[R]],--R;
            Ans[q[i].id]+=q[i].ad*res;
        }
        for(int i=1;i<=m;i++)cout<<Ans[i]<<endl;
        return 0;
    }
    100分 莫队
  • 相关阅读:
    解决virtualbox与mac文件拖拽问题
    SNMP收集
    scapy的安装
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    subprocess.call(cmd, shell=True)
    能够把意见说的让人接受是个技能
    (转)Jenkins2.0 Pipeline 插件执行持续集成发布流程
    ansible 与 Jinja2的结合 -- 安装zabbix
    运维自动化平台-背后的设计计划和架构
    命令行获取zabbix最新的issues
  • 原文地址:https://www.cnblogs.com/thmyl/p/8908984.html
Copyright © 2020-2023  润新知