zoukankan      html  css  js  c++  java
  • 【洛谷P1903】【BZOJ2120】数颜色 / 维护队列【带修莫队】

    题目大意:

    题目链接:
    洛谷:https://www.luogu.org/problemnew/show/P1903
    BZOJ:https://www.lydsy.com/JudgeOnline/problem.php?id=2120

    nn只画笔,维护以下操作:

    1. Q L RQ L R代表询问你从第LL支画笔到第RR支画笔中共有几种不同颜色的画笔。
    2. R P ColR P Col 把第PP支画笔替换为颜色ColCol

    思路:

    一开始看到这题兴奋的敲了一个分块,敲到最后才发现col106colleq 10^6而不是10510^5。。。
    正解是带修莫队。
    如果没有修改操作,那么这就是莫队的板子。
    只要加上修改就可以了。


    其实莫队的修改也是暴力。
    我们把每一个修改记录下来,然后把每一个询问前所需要的修改数也记录下来。如果询问ii比询问i1i-1多了一些修改,那么就把这些修改改好,如果少了就改回去。
    其实真的就是暴力。

    void work(int x,int i)  //要做第x次修改,这次是询问i
    {
    	if (chg[x].x>=ask[i].l&&chg[x].x<=ask[i].r)  //在区间内修改才有贡献
    	{
    		cnt[a[chg[x].x]]--;
    		if (!cnt[a[chg[x].x]]) sum--;
    		if (!cnt[chg[x].val]) sum++;
    		cnt[chg[x].val]++; 
    	}
    	swap(a[chg[x].x],chg[x].val);
    	//交换之后,如果下次要改回来时就相当于把现在的值储存到原数组里
    }
    

    带修莫队平均最有复杂度大约是取Block=n3Block=sqrt[3]{n}。证明是不可能证明的XD
    不知道为什么我敲的莫队跑的贼慢。不加Ofast,inlineOfast,inline的话要跑4s+4s+。请大佬斧正。


    代码:

    %:pragma GCC optimize("Ofast")
    %:pragma GCC optimize("inline")
    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <algorithm>
    #define rr register
    using namespace std;
    
    const int N=50010,M=1000010;
    int n,m,s,Q,T,l,r,sum,k,a[N],ans[N],cnt[M],pos[N];
    char ch;
    
    int read()
    {
    	int d=0;
    	char ch=getchar();
    	while (!isdigit(ch)) ch=getchar();
    	while (isdigit(ch))
    		d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d;
    }
    
    void write(int x)
    {
    	if (x>9) write(x/10);
    	putchar(x%10+48);
    }
    
    struct Ask
    {
    	int l,r,id,k;
    }ask[N];
    
    struct Change
    {
    	int x,val;
    }chg[N];
    
    bool cmp(Ask x,Ask y)
    {
    	if (pos[x.l]<pos[y.l]) return 1;
    	if (pos[x.l]>pos[y.l]) return 0;
    	return x.r<y.r;
    }
    
    void del(int x)
    {
    	cnt[a[x]]--;
    	if (!cnt[a[x]]) sum--;
    }
    
    void add(int x)
    {
    	if (!cnt[a[x]]) sum++;
    	cnt[a[x]]++;
    }
    
    void work(int x,int i)
    {
    	if (chg[x].x>=ask[i].l&&chg[x].x<=ask[i].r)
    	{
    		cnt[a[chg[x].x]]--;
    		if (!cnt[a[chg[x].x]]) sum--;
    		if (!cnt[chg[x].val]) sum++;
    		cnt[chg[x].val]++;
    	}
    	swap(a[chg[x].x],chg[x].val);
    }
    
    int main()
    {
    	n=read(); Q=read();
    	T=pow((double)n,(1.0/3.0));
    	for (rr int i=1;i<=n;i++)
    	{
    		a[i]=read();
    		pos[i]=(i-1)/T+1;
    	}
    	for (rr int i=1;i<=Q;i++)
    	{
    		while (ch=getchar()) if (ch=='Q'||ch=='R') break;
    		if (ch=='Q')
    		{
    			m++;
    			ask[m].l=read(); ask[m].r=read();
    			ask[m].id=m; ask[m].k=s;
    		}
    		else
    		{
    			s++;
    			chg[s].x=read(); chg[s].val=read();
    		}
    	}
    	sort(ask+1,ask+1+m,cmp);
    	l=1;
    	for (rr int i=1;i<=m;i++)
    	{
    		for (;l<ask[i].l;l++) del(l);
    		for (;l>ask[i].l;l--) add(l-1);
    		for (;r<ask[i].r;r++) add(r+1);
    		for (;r>ask[i].r;r--) del(r);
    		for (;k<ask[i].k;k++) work(k+1,i);
    		for (;k>ask[i].k;k--) work(k,i);
    		ans[ask[i].id]=sum;
    	}
    	for (rr int i=1;i<=m;i++)
    		write(ans[i]),putchar(10);
    	return 0;
    }
    
  • 相关阅读:
    SpringMVC【二、项目搭建】
    SpringMVC【一、概述】
    VUE【四、组件】
    VUE【三、指令】
    VUE【二、选项和生命周期】
    VUE【一、概述】
    BootStrap【四、插件】
    BootStrap【三、组件】
    BootStrap【二、样式】
    C#+ArcEngine创建企业数据库、连接及相关
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11997986.html
Copyright © 2011-2022 走看看