zoukankan      html  css  js  c++  java
  • [SDOI2019] 快速查询

    题意:

    给定一个长度为n的整数数列。初始的时候所有元素都为零。

    现在按照时间顺序提供了$t imes q$次关于这个数列的修改或询问,每一次修改或询问一定为以下六种情况之一:

    • 1 i val:将$a_{i}$赋值为给定整数val;
    • 2 val:将所有元素同时加上val
    • 3 val:将所有元素同时乘上val
    • 4 val:将所有元素同时赋值为val
    • 5 i:询问第$a_{i}$个元素现在的值是多少;
    • 6:询问现在所有元素的和。

    现在你求出所有询问答案之和对$10^{7}+19$取模的结果。

    $nleq 10^{9},qleq 10^{5},tleq 100,-10^{9}leq valleq 10^{9},本质不同的询问有q个$。

    题解:

    需要做到$O(1)$处理询问,所以肯定跟数据结构没关系了。

    注意到被修改过的元素最多有$10^{5}$个,那么我们可以单独维护这些元素,设该序列为V。

    然后维护一个oth表示没被修改过的元素当前的值,再维护一个当前序列之和sum。

    考虑怎么维护2,3操作,类似于线段树进行加乘,我们维护mul,add标记,满足$a_{i}=V_{i} imes mul+add$。

    注意一个极其严重的问题:如果有3 0操作那么mul标记会等于0,显然mul不能为0,所以需要把所有3 0操作改成4 0操作。

    考虑怎么维护4操作,直接平推掉序列,令$sum=val imes n,add=0,mul=1$,暂时不管V。

    考虑怎么维护1操作,先将原来的$V_{i}$从sum里减掉,新的$V'_{i}$需要满足$V'_{i} imes mul+add=val$,移项可得$V'_{i}=frac{val-add}{mul}$。

    注意到我们没把4操作的影响计入V,于是需要记录最后一次4操作和最后一次操作$V_{i}$的时间戳并比较大小:如果后者大则$V_{i}=V_{i}$,否则$V_{i}=oth$。

    复杂度$O(tq)$,其实并不难,主要是样例实在难调(

    套路:

    • 使用$lazytag$时:整体乘法标记是不能为0的。
    • 使用$lazytag$时:将“当前值”和“实际值”的关系整理清晰。
    • 线性筛逆元公式:$inv(x)=inv(p\% x) imes(p/x)$。(或者用阶乘求)

    代码:

    #include<bits/stdc++.h>
    #define maxn 100005
    #define maxm 500005
    #define inf 0x7fffffff
    #define mod 10000019
    #define ll long long
    #define rint register int
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    ll las[maxn],V[maxn],inv[mod+5]; 
    map<ll,ll> mp;
    struct Question{ll type,p,val;}Q[maxn];
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline int mo(int x){return x>=mod?x-mod:x;}
    
    int main(){
        ll n=read(),q=read();
        for(rint i=1;i<=q;i++){
            Q[i].type=read();
            if(Q[i].type==1) Q[i].p=read(),Q[i].val=(read()%mod+mod)%mod,mp[Q[i].p]=i;
            else if(Q[i].type==2) Q[i].val=(read()%mod+mod)%mod; 
            else if(Q[i].type==3){
                Q[i].val=(read()%mod+mod)%mod; 
                if(Q[i].val==0) Q[i].type=4;
            }
            else if(Q[i].type==4) Q[i].val=(read()%mod+mod)%mod; 
            else if(Q[i].type==5) Q[i].p=read();
        }
        ll T=read(),sum=0,mul=1,add=0,oth=0,ans=0;
        inv[1]=1; for(rint i=2;i<mod;i++) inv[i]=mod-inv[mod%i]*(mod/i)%mod;
        for(rint t=1;t<=T;t++){
            ll a=read(),b=read();
            for(rint j=1;j<=q;j++){
                ll i=(a+j*b)%q+1;
                if(Q[i].type==1){
                    ll x=mp[Q[i].p];
                    if(las[0]>las[x]) sum=mo(sum-oth+mod);
                    else sum=mo(sum-mo(V[x]*mul%mod+add)+mod);
                    V[x]=mo(Q[i].val-add+mod)*inv[mul]%mod;
                    sum=mo(sum+mo(V[x]*mul%mod+add)),las[x]=q*(t-1)+j;
                }
                if(Q[i].type==2) sum=mo(sum+n*Q[i].val%mod),add=mo(add+Q[i].val),oth=mo(oth+Q[i].val);
                if(Q[i].type==3) sum=sum*Q[i].val%mod,mul=mul*Q[i].val%mod,add=add*Q[i].val%mod,oth=oth*Q[i].val%mod;
                if(Q[i].type==4) sum=Q[i].val*n%mod,mul=1,add=0,oth=Q[i].val,las[0]=q*(t-1)+j;
                if(Q[i].type==5){
                    if(!mp[Q[i].p]) ans=mo(ans+oth);
                    else{
                        ll x=mp[Q[i].p];
                        if(las[0]>las[x]) ans=mo(ans+oth);
                        else ans=mo(ans+mo(V[x]*mul%mod+add));
                    }
                }
                if(Q[i].type==6) ans=mo(ans+sum);
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    [SDOI2019] 快速查询
  • 相关阅读:
    vue 把后端返回的图片和url链接生成的二维码用canvas 合成一张图片
    Dart和JavaScript对比小结
    webgl学习,知识储备
    nightwatch+selenium做e2e自动化测试采坑小计
    linux centos7 环境变量设置
    ES6学习笔记
    SQLserver数据库还原语句
    AngularJs的那些坑(持续更新...)
    Hosting socket.io WebSocket apps in IIS using iisnode
    mongodb 数据库操作--备份 还原 导出 导入
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13080748.html
Copyright © 2011-2022 走看看