首页 > 其他分享 >粒子消消乐

粒子消消乐

时间:2024-09-24 20:13:17浏览次数:6  
标签:粒子 la int while 400005 消消 ans

  • “跳跃”的过程往往可以用倍增优化(一长段相同的粒子)
  • 【发散思维】根据鸽巢原理,最后剩下的粒子至多26个,但直接从这一点入手不好做。从这一条性质出发,我们还能推出什么?剩下的粒子两两之间被消掉的段数是有限的!
  • 26*19看起来挺大的,但其实不就是log^2嘛!有2s时限,n=200000完全可过的
点击查看代码
#include <bits/stdc++.h>
using namespace std;
char s[400005];
int f[400005][19],b[400005],g[400005];
int la[105];
int n,q;
void pre()
{
    for(int j=1;j<=18;j++)
    {
        for(int i=1;i<2*n;i++)
        {
            if(f[i][j-1]==-1)
            {
                f[i][j]=-1;
            }
            else
            {
                f[i][j]=f[f[i][j-1]][j-1];
            }
            if(f[i][j]!=-1)
            {
                g[i]=j;
            }
        }
    }
}
void refresh()
{
    for(int j=0;j<=18;j++)
    {
        for(int i=1;i<2*n;i++)
        {
            f[i][j]=-1;
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    memset(f,-1,sizeof(f));
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>q;
        for(int i=1;i<=n;i++)
        {
            cin>>s[i];
            s[i+n]=s[i];
        }
        for(int i=1;i<=n;i++)
        {
            cin>>b[i];
            b[i+n]=b[i];
        }
        memset(la,0,sizeof(la));
        for(int i=1;i<2*n;i++)
        {
            f[i][0]=-1;
            g[i]=-1;
        }
        for(int i=1;i<2*n;i++)
        {
            f[la[s[i]]][0]=i+1;
            g[la[s[i]]]=0;
            la[s[i]]=i;
        }
        pre();
        for(int i=1;i<=q;i++)
        {
            int opt,u,v;
            cin>>opt>>u>>v;
            if(opt==1)
            {
                b[u]=b[u+n]=v;
            }
            else
            {
                if(u>v)
                {
                    v+=n;
                }
                int p=u;
                long long ans=0;
                while(p<=v)
                {
                    if(g[p]==-1||f[p][0]>v+1)
                    {
                        ans+=b[p];
                        p++;
                        continue;
                    }
                    for(int j=g[p];j>=0;j--)
                    {
                        if(f[p][j]!=-1&&f[p][j]<=v+1)
                        {
                            p=f[p][j];
                        }
                    }
                }
                cout<<ans<<endl;
            }    
        }
        refresh();
    }
    return 0;
}

标签:粒子,la,int,while,400005,消消,ans
From: https://www.cnblogs.com/watersail/p/18429922

相关文章