zoukankan      html  css  js  c++  java
  • P3709 大爷的字符串题

    题意

    询问区间众数出现的次数

    思路

    唯有水题快人心
    离散化+莫队
    莫队一定要先加后减,有事会出错的
    莫队维护区间众数:
    维护两个数组,一个数组记录权值为x的出现次数,一个记录出现次数为x的数的个数
    add很简单,更新ans
    delete的时候,删除的是ans话,查看出现次数为x的个数是否为1,是就ans--(这里删除后至少为ans--),不是就和ans无关

    代码

    #include <bits/stdc++.h>
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int maxn=200007;
    int a[maxn],b[maxn],n,m;
    int ans,belong[maxn],vis[maxn],num[maxn];
    struct node {
    	int s,t,id;
    	int ans;
    	bool operator < (const node &b) const {
    		return belong[s]==belong[b.s] ? t<b.t : s<b.s ;
    	}
    }Q[maxn];
    bool cmp(node a,node b)
    {
    	return a.id<b.id;
    }
    void add(int x)
    {
    	num[vis[x]]--;
    	vis[x]++;
    	if(ans<vis[x]) ans++;
    	num[vis[x]]++;
    }
    void delet(int x)
    {
    	if(ans==vis[x] && num[vis[x]]==1) ans--;
    	num[vis[x]]--;
    	vis[x]--;
    	num[vis[x]]++;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int k=sqrt(n);
    	FOR(i,1,n) scanf("%d",&a[i]),b[i]=a[i];
    	sort(b+1,b+1+n);
    	FOR(i,1,n)	a[i]=lower_bound(b+1,b+1+n,a[i])-b;
    	FOR(i,1,n) belong[i]=(i-1)/k+1;
    	FOR(i,1,m) scanf("%d%d",&Q[i].s,&Q[i].t),Q[i].id=i;
    	sort(Q+1,Q+1+m);
    	int l=1,r=0;
    	FOR(i,1,m)
    	{
    		while(l > Q[i].s) add(a[--l]);
    		while(l < Q[i].s) delet(a[l++]);
    		while(r < Q[i].t) add(a[++r]);
    		while(r > Q[i].t) delet(a[r--]);
    		Q[i].ans=max(ans,0);
    	}
    	sort(Q+1,Q+1+m,cmp);
    	FOR(i,1,m) printf("%d
    ",-Q[i].ans);
    	return 0;
    }
    
  • 相关阅读:
    iOS中的imageIO与image解码
    在asp.net 中生成PDF的方法
    asp.net中模拟测试smtp发邮件
    ASP.NET导入EXCEL方法汇总
    在asp.net中使用加密数据库联接字符串
    CSS实现限制字数功能
    在ASP.NET中备份和还原数据库
    说说ASP.NET的IsPostBack
    javascript小技巧之with()方法
    CSS中filter滤镜的学习笔记
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9811898.html
Copyright © 2011-2022 走看看