luogu3823 [NOI2017] earthworms queuing

[NOI2017] earthworms queuing

Why do I feel naked ah T2 than T1

A breakthrough is \ (k \ Leq 50 \) , we can directly maintain the current string length \ (\ leq k \) of all sub-strings \ (\ hash) value, \ (3 \) time complexity becomes operational a \ (O (\ sum | S |) \)

How to consider maintaining \ (2 \) operation (in fact, this implies an operation is also very obvious), we have to be quick off the merger and by maintaining a linked list, every merger or off when direct \ (O ( k ^ 2) \) maintenance \ (hash \) increase or decrease in value, calmly analyze, then find the time complexity should actually \ (O ((n + c ) k ^ 2) \) , and it is clear that \ (k ^ 2 \) is run discontent

But it is still better to write

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef unsigned long long ull;
const int N=200000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define p 10000009
#define bas 7
#define eps 1e-8
#define K 50
struct node{
    int cnt,nxt;ull val;
}hsh[20020000];
int all=0,head[p+10];

int n,m,num[200200],pre[200200],suf[200200];
ull pw[200200];
char s[10000200];

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void insert(ull x,int val)
{
    int u=x%p,i;
    for (i=head[u];i;i=hsh[i].nxt)
    {
        if (hsh[i].val==x)
        {
            hsh[i].cnt+=val;
            return;
        }
    }
    hsh[++all].val=x;hsh[all].cnt=val;hsh[all].nxt=head[u];head[u]=all;
}

int query(ull x)
{
    int i,u=x%p;
    for (i=head[u];i;i=hsh[i].nxt)
    {
        if (hsh[i].val==x) return hsh[i].cnt;
    }
    return 0;
}

int main()
{
    n=read();m=read();
    pw[0]=1;
    rep(i,1,N) pw[i]=pw[i-1]*bas;
    rep(i,1,n)
    {
        num[i]=read();
        insert(num[i],1);
    }
    while (m--)
    {
        int op=read();
        if (op==1)
        {
            int x=read(),y=read();
            pre[y]=x;suf[x]=y;
            int i,pcnt=1;ull now=0;
            for (i=x;i && pcnt<=K;i=pre[i],pcnt++)
            {
                now+=(pw[pcnt-1]*num[i]);
                ull tmp=now;int j,tot=pcnt+1;
                for (j=y;j && tot<=K;j=suf[j],tot++)
                {
                    tmp=tmp*bas+num[j];
                    insert(tmp,1);
                }
            }
        }
        else if (op==2)
        {
            int x=read(),y=suf[x];
            pre[y]=0;suf[x]=0;
            int i,pcnt=1;ull now=0;
            for (i=x;i && pcnt<=K;i=pre[i],pcnt++)
            {
                now+=(pw[pcnt-1]*num[i]);
                ull tmp=now;int j,tot=pcnt+1;
                for (j=y;j && tot<=K;j=suf[j],tot++)
                {
                    tmp=tmp*bas+num[j];
                    insert(tmp,-1);
                }
            }
        }
        else
        {
            scanf("%s",s+1);
            int k=read(),len=strlen(s+1);
            ull now=0;ll ans=1;
            rep(i,1,len)
            {
                //cout << now << endl;
                now=now*bas+(s[i]-'0');
                //cout << now << endl;
                if (i>=k)
                {
                    ans=ans*query(now)%maxd;
                    now-=((s[i-k+1]-'0')*pw[k-1]);
                }
                //cout << now << endl << endl;
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}
/*
5 9
3 1 3 5 3
3 333135 2
3 333135 1
1 1 3
1 2 5
1 3 2
1 5 4
3 333135 2
3 333135 1
3 333135 3
 */

Guess you like

Origin www.cnblogs.com/encodetalker/p/11141334.html