zoukankan      html  css  js  c++  java
  • Ahoi2013 作业

    3236: [Ahoi2013]作业

    Time Limit: 100 Sec  Memory Limit: 512 MB

    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

    Source

    By wangyisong1996加强数据

    莫队+树状数组

    用莫队解决[l,r]的问题

    两个树状数组,以权值为下标,一个记录权值为i的是否出现,一个记录权值为i的出现了几次

    蒟蒻初学,常数巨大。。。

    向各位大佬请教如何优化

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define N 100001
    using namespace std;
    int n,m,size,l=1,r,tmp;
    int key[N],sum[N],c[2][N];
    int ans[N*10][2];
    struct node
    {
        int l,r,a,b;
        int bl,id;
        int ans1,ans2;
    }e[N*10];
    bool cmp(node p,node q)
    {
        if(p.bl!=q.bl) return p.bl<q.bl;
        return p.r<q.r;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    void change(int k,int w,int h)
    {
        while(k<=n) { c[h][k]+=w; k+=lowbit(k);}
    }
    int query(int k,int h)
    {
        int tot=0;
        while(k) { tot+=c[h][k]; k-=lowbit(k);}
        return tot;
    }
    void update(int k,int w)
    {
        sum[key[k]]+=w; 
        change(key[k],w,1);
        if(w==1&&sum[key[k]]==1) change(key[k],1,0);
        else if(w==-1&&!sum[key[k]]) change(key[k],-1,0);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        size=sqrt(n);
        for(int i=1;i<=n;i++) scanf("%d",&key[i]);
        for(int i=1;i<=m;i++) 
        {
            scanf("%d%d%d%d",&e[i].l,&e[i].r,&e[i].a,&e[i].b);
            e[i].bl=(e[i].l-1)/size+1;
            e[i].id=i;
        }
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=m;i++)
        {
            while(e[i].l<l) update(--l,1);
            while(e[i].l>l) update(l++,-1);
            while(e[i].r<r) update(r--,-1);
            while(e[i].r>r) update(++r,1);
            e[i].ans1=query(e[i].b,0)-query(e[i].a-1,0);
            e[i].ans2=query(e[i].b,1)-query(e[i].a-1,1);
        }
        for(int i=1;i<=m;i++) ans[e[i].id][0]=e[i].ans2 , ans[e[i].id][1]=e[i].ans1;
        for(int i=1;i<=m;i++) printf("%d %d
    ",ans[i][0],ans[i][1]);
    }
  • 相关阅读:
    ngx_lua_waf完整安装说明
    Linux(CentOS)下的JDK的安装和环境配置
    Genymotion的2个问题及解决方法
    Appscan的第一个测试请求就是提交MAC地址
    oracle相关知识
    数据结构之树
    kafka的写入内存?硬盘
    算法的时间复杂度和空间复杂度
    Java线程池
    mapReduce和spark的shuffle
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6773084.html
Copyright © 2011-2022 走看看