码迷,mamicode.com
首页 > 其他好文 > 详细

CF418E Tricky Password(未完待续)

时间:2020-07-28 22:45:37      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:fine   wap   出现   lang   str   turn   i++   for   sort   

https://www.luogu.com.cn/problem/CF418E

分块

找规律,可以发现每两行(除第一行外)形成一个循环

所以我们只要求解前三行数据就可以了

\[定义:\第一行为:a_{1},a_{2},\cdots ,a_{m}\第二行为:b_{1},b_{2},\cdots ,b_{m}\第三行为:c_{1},c_{2},\cdots ,c_{m}\f_{i,j}表示前i块中j在a中出现了几次\g_{i,j}表示前i块中j在b中出现了几次\修改操作暴力更新每个块即可 \]

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 200005
using namespace std;
int xx,yy,B;
int n,m,k,km,cc,lar,a[N],d[N],l[N],r[N],bel[N];
int x,y,opt,w;
int f[105][200005],g[105][200005];
struct Ques
{
    int opt,x,y;
}q[N];
inline int read()
{
    int s=0;
    char c=getchar();
    while (!isdigit(c))
        c=getchar();
    while (isdigit(c))
    {
        s=s*10+c-‘0‘;
        c=getchar();
    }
    return s;
}
int main()
{
    m=read();
    for (int i=1;i<=m;i++)
        a[i]=read(),d[i]=a[i];
    k=read();
    km=m;
    for (int i=1;i<=k;i++)
    {
        q[i].opt=read(),q[i].x=read(),q[i].y=read();
        if (q[i].opt==1)
        {
            swap(q[i].x,q[i].y);
            d[++km]=q[i].y;
        }
    }
    sort(d+1,d+km+1);
    cc=unique(d+1,d+km+1)-d-1;
    for (int i=1;i<=m;i++)
        a[i]=lower_bound(d+1,d+cc+1,a[i])-d;
    for (int i=1;i<=k;i++)
        if (q[i].opt==1)
            q[i].y=lower_bound(d+1,d+cc+1,q[i].y)-d;
    B=(int)sqrt(m)+1;
    if (m/B+1>100)
        B=1000;
    for (int i=1;i<=m;i++)
    {
        bel[i]=i/B+1;
        if (!l[bel[i]])
            l[bel[i]]=i;
        r[bel[i]]=i;
    }
    for (int i=1;i<=bel[m];i++)
    {
        lar=0;
        for (int j=0;j<=cc;j++)
            f[i][j]=f[i-1][j],lar=max(lar,f[i-1][j]);
        for (int j=0;j<=lar;j++)
            g[i][j]=g[i-1][j];
        for (int j=l[i];j<=r[i];j++)
        {
            f[i][a[j]]++;
            g[i][f[i][a[j]]]++;
        }
    }
    for (int i=1;i<=k;i++)
    {
        x=q[i].x,y=q[i].y,opt=q[i].opt;
        if (opt==2)
        {
            if (x==1)
                printf("%d\n",d[a[y]]); else
            if (x%2==0)
            {
                w=bel[y]-1;
                for (int j=l[w+1];j<=y;j++)
                    f[w][a[j]]++;
                printf("%d\n",f[w][a[y]]);
                for (int j=l[w+1];j<=y;j++)
                    f[w][a[j]]--;
            } else
            {
                w=bel[y]-1;
                for (int j=l[w+1];j<=y;j++)
                    f[w][a[j]]++,g[w][f[w][a[j]]]++;
                printf("%d\n",g[w][f[w][a[y]]]);
                for (int j=l[w+1];j<=y;j++)
                    g[w][f[w][a[j]]]--,f[w][a[j]]--;
            }
        } else
        {
            w=bel[x];
            for (int j=w;j<=bel[m];j++)
            {
                g[j][f[j][a[x]]]--;
                f[j][a[x]]--;
            }
            a[x]=y;
            for (int j=w;j<=bel[m];j++)
            {
                f[j][a[x]]++;
                g[j][f[j][a[x]]]++;
            }
        }
    }
    return 0;
}

CF418E Tricky Password(未完待续)

标签:fine   wap   出现   lang   str   turn   i++   for   sort   

原文地址:https://www.cnblogs.com/GK0328/p/13393857.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!