zoukankan      html  css  js  c++  java
  • 并不对劲的loj3110:p5358:[SDOI2019]快速查询

    题目大意

    (n)个数,对这些数进行(t imes q)次操作,操作有单点修改、全局加、全局乘、全局修改、单点询问、全局求和这几种。
    (t imes q)次操作中,每次操作都是来自于给出的(q)次基本操作之一。输出所有询问操作的和模(10^7+19)
    (nleq 10^9;qleq 10^5;tleq 100;-10^9leq 操作中涉及的值 leq 10^9)

    题解

    只用存(leq 10^5)个单点修改操作涉及的点。
    正常的做法:维护全局加标记、乘标记、修改标记,单点修改时将这个点的值改为((值+加法逆元) imes 乘法逆元)
    并不对劲的做法:维护每个时刻的加标记、乘标记、修改标记、每个点上次修改的时刻,单点查询时,如果该点上次的修改操作是单点修改,值=((修改的数 imes 当前乘标记 imes修改时乘标记的逆元)+(当前加标记+修改时加标记的逆元 imes(当前乘标记 imes修改时乘标记的逆元)))
    预处理逆元。

    代码
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
    #define view(u,k) for(int k=fir[u];~k;k=nxt[k])
    #define maxn 100007
    #define maxx 10000027
    #define maxm 10000007
    #define LL long long
    using namespace std;
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    void write(int x)
    {
    	if(x==0){putchar('0'),putchar('
    ');return;}
    	int f=0;char ch[20];
    	if(x<0)putchar('-'),x=-x;
    	while(x)ch[++f]=x%10+'0',x/=10;
    	while(f)putchar(ch[f--]);
    	putchar('
    ');
    	return;
    }
    int t,a[maxn],b[maxn],n,q,pw[maxx],ny[maxx],mulmk[maxm],admk[maxm],lst[maxn],mkx[maxn],num[maxn],cntn,lstmk;
    int qf[maxn],qx[maxn],qy[maxn],ans,nowsum;
    const int mod=1e7+19;
    int mul(int x,int y){int res=1;while(y){if(y&1)res=(LL)res*x%mod;x=(LL)x*x%mod,y>>=1;}return res;}
    int getrk(int k)
    {
    	int L=1,R=cntn,res=cntn+1;
    	while(L<=R)
    	{
    		int mid=(L+R)>>1;
    		if(num[mid]>=k)res=min(res,mid),R=mid-1;
    		else L=mid+1;
    	}
    	return res;
    }
    int mo(int x){if(x<0)return x+mod;return x>=mod?x-mod:x;}
    int main()
    {
    	pw[0]=1;rep(i,1,mod-1)pw[i]=(LL)pw[i-1]*i%mod;
    	ny[mod-1]=mul(pw[mod-1],mod-2);dwn(i,mod-2,0)ny[i]=(LL)ny[i+1]*(i+1)%mod;
    	rep(i,1,mod-1)ny[i]=(LL)ny[i]*pw[i-1]%mod;
    	n=read(),q=read();
    	rep(i,1,q)
    	{
    		qf[i]=read();
    		if(qf[i]==6)continue;
    		else if(qf[i]==1)qx[i]=read(),qy[i]=mo(read()%mod);
    		else qx[i]=read(); 
    		if(qf[i]==1)num[++cntn]=qx[i];
    		if(qf[i]==2||qf[i]==3||qf[i]==4)qx[i]=mo(qx[i]%mod);
    	}
    	t=read();
    	sort(num+1,num+cntn+1);
    	rep(i,1,t)a[i]=read(),b[i]=read();
    	rep(i,1,q)
    	{
    		if(qf[i]==1){qx[i]=getrk(qx[i]);}
    		else if(qf[i]==5){int qq=getrk(qx[i]);if(num[qq]==qx[i])qx[i]=qq;else qx[i]=-1;}
    		if(qf[i]==3&&qx[i]==0)qf[i]=4;
    	}
    	admk[0]=0,mulmk[0]=1;n%=mod;
    	rep(i,1,t)rep(j,1,q)
    	{
    		int p=((LL)a[i]+(LL)j*b[i])%q+1,pp=(i-1)*q+j;
    		if(qf[p]==1)
    		{
    			int val=0;admk[pp]=admk[pp-1],mulmk[pp]=mulmk[pp-1];
    			if(lstmk>=lst[qx[p]])val=admk[pp];
    			else val=mo((LL)mkx[qx[p]]*mulmk[pp]%mod*ny[mulmk[lst[qx[p]]]]%mod+mo(admk[pp]-(LL)admk[lst[qx[p]]]*mulmk[pp]%mod*ny[mulmk[lst[qx[p]]]]%mod));
    			nowsum=mo(nowsum+mo(qy[p]-val)),lst[qx[p]]=pp,mkx[qx[p]]=qy[p]; 
    		}
    		else if(qf[p]==2)
    		{
    			admk[pp]=mo(admk[pp-1]+qx[p]),mulmk[pp]=mulmk[pp-1];
    			nowsum=mo(nowsum+(LL)n*qx[p]%mod);
    		}
    		else if(qf[p]==3)
    		{
    			admk[pp]=(LL)admk[pp-1]*qx[p]%mod,mulmk[pp]=(LL)mulmk[pp-1]*qx[p]%mod;
    			nowsum=(LL)nowsum*qx[p]%mod;
    		}
    		else if(qf[p]==4)
    		{
    			lstmk=pp,admk[pp]=qx[p],mulmk[pp]=1;
    			nowsum=(LL)n*qx[p]%mod;
    		}
    		else if(qf[p]==5)
    		{
    			admk[pp]=admk[pp-1],mulmk[pp]=mulmk[pp-1];
    			if(qx[p]<0)ans=mo(ans+admk[pp]);
    			else 
    			{
    				if(lstmk>=lst[qx[p]])ans=mo(ans+admk[pp]);
    				else ans=mo(ans+mo((LL)mkx[qx[p]]*mulmk[pp]%mod*ny[mulmk[lst[qx[p]]]]%mod+mo(admk[pp]-(LL)admk[lst[qx[p]]]*mulmk[pp]%mod*ny[mulmk[lst[qx[p]]]]%mod)));
    			}
    		}
    		else{
    			admk[pp]=admk[pp-1],mulmk[pp]=mulmk[pp-1];ans=mo(ans+nowsum);}
    	}
    	write(ans);
    	return 0;
    }
    
  • 相关阅读:
    java多线程编程(一)
    java的本地文件操作
    Java基础总结(二)
    Gym 100851 Distance on Triangulation
    Gym 100851 题解
    Gym 101482 题解
    CodeForces Round 521 div3
    zoj 5823 Soldier Game 2018 青岛 I
    CodeForces round 520 div2
    CodeForces 1042 F Leaf Sets 贪心
  • 原文地址:https://www.cnblogs.com/xzyf/p/13086809.html
Copyright © 2011-2022 走看看