zoukankan      html  css  js  c++  java
  • 2021“MINIEYE杯”中国大学生算法设计超级联赛(1)1010 zoto

    https://acm.hdu.edu.cn/contests/contest_showproblem.php?cid=984&pid=1010

    题意:

    给出二维平面上的若干个点和若干个矩形,查询每个矩形内部有多少个y坐标不一样的点

    莫队算法,将矩形按左右边界排序,查询上下边界的y坐标不一样的点

    可以用数字证书,也可以继续分块

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 100002
    
    #define lowbit(x) (x&-x)
    
    int f[N];
    struct node
    {
        int l,d,r,u;
        int id;
        int ans;
        int pos;
    }e[N];
    
    int c[N],sum[N]; 
    
    int n,m,S;
    
    bool cmp(node p,node q)
    {
        if(p.pos!=q.pos) return p.pos<q.pos; 
        return p.r<q.r;
    }
    
    bool id(node p,node q)
    {
        return p.id<q.id;
    }
    
    void add(int x,int y)
    {
        while(x<N)
        {
            c[x]+=y;
            x+=lowbit(x);
        }
    }
    
    int query(int x)
    {
        int cnt=0;
        while(x)
        {
            cnt+=c[x];
            x-=lowbit(x); 
        }
        return cnt;
    }
    
    void update(int x,int k)
    {
        x=f[x];
        sum[x]+=k;
        if(k==1 && sum[x]==1) add(x,1);
        else if(k==-1 && !sum[x]) add(x,-1);
    }
    
    void solve()
    {
        int l=1,r=0;
        for(int i=1;i<=m;i++)
        {
            while(l<e[i].l) update(l++,-1);
            while(l>e[i].l) update(--l,1);
            while(r<e[i].r) update(++r,1);
            while(r>e[i].r) update(r--,-1);
            e[i].ans=query(e[i].u)-query(e[i].d-1);
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            memset(c,0,sizeof(c));
            memset(sum,0,sizeof(sum));
            S=sqrt(n);
            for(int i=1;i<=n;i++) 
            {
                scanf("%d",&f[i]);
                ++f[i];
            }
            for(int i=1;i<=m;i++)
             {
                scanf("%d%d%d%d",&e[i].l,&e[i].d,&e[i].r,&e[i].u);
                e[i].u++;
                e[i].d++;
                e[i].id=i;
                e[i].pos=(e[i].l-1)/S+1;
            }
            sort(e+1,e+m+1,cmp);
            solve();
            sort(e+1,e+m+1,id);
            for(int i=1;i<=m;i++) printf("%d
    ",e[i].ans);
        }
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    find the safest road HDU
    分页存储过程
    .NET Core与.NET Framework、Mono之间的关系
    winForm开发
    面试题目总结
    sqlserver锁表、解锁、查看锁表
    架构漫谈(四):如何做好架构之架构切分
    多线程讲解
    递归菜单简单应用
    杂记
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15070766.html
Copyright © 2011-2022 走看看