Luogu5358 [SDOI2019]快速查询

Luogu5358 [SDOI2019]快速查询

不敢压行了,调不动\(QAQ\)。

注意查询散列表时,如果已经找到了数,但是是在覆盖以前的,直接返回找不到即可,因为散列表的特点是后插入的数先访问到。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100005
#define M 105
#define ll long long
#define il inline
#define rint register int
using namespace std;
const int p=10000019;
int n,q,t,nt=0,tot=0,allnum=0,s=0,add=0,mul=1,fr[p+25],nxt[p+25],d1[p+25],d2[p+25],inv[p+5],a[M],b[M];
int cnt=0;
ll ans=0;
struct node
{
    int opt;
    int x,val;
}ask[N];
il void Add(int x,int y)
{
    int key=x%p;
    ++tot,d1[tot]=x,d2[tot]=y,nxt[tot]=fr[key],fr[key]=tot;
}
il int getpos(int x)
{
    int key=x%p;
    for (rint i=fr[key];i;i=nxt[i])
    {
        ++cnt;
        if (d1[i]==x)
            return (i>nt)?i:-1;
    }
    return -1;
}
il int rval(int x)
{
    return ((ll)mul*x+add)%p;
}
il int tval(int x)
{
    mul=(mul+p)%p;
    return (ll)(x-add)*inv[mul]%p;
}
int main()
{
    inv[1]=1;
    for (rint i=2;i<p;++i)
        inv[i]=(ll)(p-p/i)*inv[p%i]%p;
    scanf("%d",&n),scanf("%d",&q);
    for (rint i=1;i<=q;++i)
    {
        scanf("%d",&ask[i].opt);
        if (ask[i].opt==1)
            scanf("%d%d",&ask[i].x,&ask[i].val); else
        if (ask[i].opt==5)
            scanf("%d",&ask[i].x); else
        if (ask[i].opt!=6)
            scanf("%d",&ask[i].val);
    }
    scanf("%d",&t);
    for (rint i=1;i<=t;++i)
        scanf("%d%d",&a[i],&b[i]);
    for (rint i=1;i<=t*q;++i)
    {
        int ct=(i-1)%q+1,par=(i-ct)/q+1,t,k=((ll)a[par]+(ll)ct*b[par])%q+1;
        if (ask[k].opt==1)
            t=getpos(ask[k].x),(t==-1)?(((s-=rval(allnum))+=ask[k].val)%=p,Add(ask[k].x,tval(ask[k].val))):(((s-=rval(d2[t]))+=ask[k].val)%=p,(void)(d2[t]=tval(ask[k].val))); else
        if (ask[k].opt==2)
            (add+=ask[k].val)%=p,s=((ll)s+(ll)n*ask[k].val)%p; else
        if (ask[k].opt==3)
            add=(ll)add*ask[k].val%p,mul=(ll)mul*ask[k].val%p,s=(ll)s*ask[k].val%p; else
        if (ask[k].opt==4)
            add=0,mul=1,nt=tot,allnum=ask[k].val,s=(ll)n*ask[k].val%p; else
        if (ask[k].opt==5)
            t=getpos(ask[k].x),ans+=((t==-1)?rval(allnum):rval(d2[t])); else
            ans+=s;
    }
    ans=(ans%p+p)%p;
    printf("%lld\n",ans);
    return 0;
}
上一篇:P5360 [SDOI2019]世界地图 虚树+最小生成树


下一篇:[SDOI2019] 热闹的聚会与尴尬的聚会