P1903 [国家集训队]数颜色

题意

带修莫队与普通莫队的区别在于加入了一个时间轴,具体可以看这篇博客

另外,这是卡常神题。

code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC target("fma","avx2")
#pragma GCC target("xop","fma4")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
#pragma GCC diagnostic error "-fwhole-program"
#pragma GCC diagnostic error "-fcse-skip-blocks"
#pragma GCC diagnostic error "-funsafe-loop-optimizations"
#include<bits/stdc++.h>
using namespace std;
#define re register
const int maxn=150010;
const int maxm=150010;
int n,m,cnt1,cnt2,nowtim,nowl=1,nowr,nowans;
int a[maxn],b[maxn],pos[maxn],cnt[1000010],ans[maxm];
struct Query{int tim,l,r,id;}qr[maxm];
struct Change{int pos,last,now;}ctim[maxm];
inline bool cmp(Query x,Query y){return pos[x.l]==pos[y.l]?(pos[x.r]==pos[y.r]?x.tim<y.tim:x.r<y.r):x.l<y.l;}
inline int read()
{
    char c=getchar();re int res=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    return res*f;
}
inline void add(int x)
{
    cnt[x]++;
    if(cnt[x]==1)nowans++;
}
inline void del(int x)
{
    cnt[x]--;
    if(!cnt[x])nowans--;
}
inline void move(int pos,int k)
{
    if(pos>=nowl&&pos<=nowr)del(a[pos]),a[pos]=k,add(a[pos]);
    a[pos]=k;
}
int main()
{
    n=read(),m=read();
    for(re int i=1;i<=n;i++)a[i]=b[i]=read();
    for(re int i=1;i<=m;i++)
    {
        char op[10];scanf("%s",op);
        re int x=read(),y=read();
        if(op[0]=='Q')qr[++cnt1]=(Query){cnt2,x,y,cnt1};
        else ctim[++cnt2]=(Change){x,b[x],y},b[x]=y;
    }
    re int t=pow(n,1.0*5/7);
    for(re int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    sort(qr+1,qr+cnt1+1,cmp);
    for(re int i=1;i<=cnt1;i++)
    {
        while(nowtim<qr[i].tim)move(ctim[nowtim+1].pos,ctim[nowtim+1].now),nowtim++;
        while(nowtim>qr[i].tim)move(ctim[nowtim].pos,ctim[nowtim].last),nowtim--;
        while(nowl>qr[i].l)add(a[--nowl]);
        while(nowl<qr[i].l)del(a[nowl++]);
        while(nowr>qr[i].r)del(a[nowr--]);
        while(nowr<qr[i].r)add(a[++nowr]);
        ans[qr[i].id]=nowans;
    }
    for(re int i=1;i<=cnt1;i++)printf("%d\n",ans[i]);
    return 0;
}
上一篇:12. 星际争霸之php设计模式--模板模式


下一篇:keil mdk+stm32的ac5和 ac6两个编译器下的字节对齐操作方法