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

    题目链接

    吐槽

    竟然让(nlog)的做法卡过去了。。

    思路

    因为(1 le q le 10^5),所以可以先对每个标准操作,所操作的位置进行重标号。这样所有的下标都是在(10^5)以内的。

    乘和加操作都可以写成(kx+b)的形式。然后对于这些操作维护一个前缀。然后就可以得到一个区间内的操作了。

    区间查询我们只要找个(TOT)来维护一下当前的所有元素和,就行了。

    单点查询,观察其上次赋值的时间。如果早于集体赋值,那么就输出当前大多数的值。

    否则就将其上次赋的值乘上从上次赋值到当前时间点这个时间段内的操作。

    代码

    /*
    * @Author: wxyww
    * @Date:   2019-05-07 20:58:04
    * @Last Modified time: 2019-05-11 10:33:03
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N = 100010,mod = 1e7 + 19;
    map<int,int>ma;
    ll read() {
    	ll x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9') {
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9') {
    		x=x*10+c-'0';
    		c=getchar();
    	}
    	return x*f;
    }
    struct node {
    	int opt,pos,val;
    }que[N];
    int TOT,s[N],a[N],b[N],now,inv[mod + 1],n,T,Q,mul[N * 100],add[N * 100];
    int lst[N],LAST;
    int query(int x,int num) {
    	if(lst[x] <= LAST) return now;
    	int cheng = 1ll * mul[num] * inv[mul[lst[x]]] % mod;
    	int jia = (add[num] - 1ll * add[lst[x] - 1] * cheng % mod + mod) % mod;
    	return (1ll * s[x] * cheng % mod + jia) % mod;
    }
    int ans;
    void solve(int x,int num) {
    	int opt = que[x].opt,pos = que[x].pos,val = que[x].val % mod;
    	mul[num] = mul[num - 1],add[num] = add[num - 1];
    	if(opt == 1) {
    		TOT -= query(pos,num);
    		TOT += val;
    		TOT = (TOT % mod + mod) % mod;
    		lst[pos] = num;
    		s[pos] = val;
    	}
    	else if(opt == 2) {
    		TOT += (1ll * n * val % mod + mod) % mod;
    		TOT = (TOT % mod + mod) % mod;
    		add[num] += val;
    		add[num] = (add[num] %mod + mod) % mod;
    		now += val;
    		now = (now % mod + mod) % mod;
    	}
    	else if(opt == 3) {
    		TOT = (1ll * TOT * val % mod + mod) % mod;
    		now = (1ll * now * val % mod + mod) % mod;
    		add[num] = (1ll * add[num] * val % mod + mod) % mod;
    		mul[num] = (1ll * mul[num] * val % mod + mod) % mod;
    	}
    	else if(opt == 4) { 
    		TOT = (1ll * val * n % mod + mod) % mod;
    		mul[num] = 1;add[num] = 0;
    		now = val;
    		LAST = num;
    	}
    	else if(opt == 5) ans += query(pos,num),ans = (ans % mod + mod) % mod;
    	else ans = ((ans + TOT) % mod + mod) % mod;
    }
    int main() {
    	n = read(),Q = read();
    	for(int i = 1;i <= Q;++i) {
    		int opt = que[i].opt = read();
    		if(opt == 1) {
    			que[i].pos = read();que[i].val = read();
    		}
    		else if(opt == 6) continue;
    		else if(opt == 5) que[i].pos = read();
    		else que[i].val = read();
    	}
    
    	inv[1] = 1;
    	for(int i =  2;i < mod;++i) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
    
    	int js = 0;
    	for(int i = 1;i <= Q;++i) {
    		if(!que[i].pos) continue;
    		if(!ma[que[i].pos]) 	ma[que[i].pos] = ++js;
    		que[i].pos = ma[que[i].pos];
    	}
    
    	int T = read(),num = 0;
    	for(int i = 1;i <= T;++i) a[i] = read(),b[i] = read();
    	for(int i = 1;i <= T;++i)
    		for(int j = 1;j <= Q;++j)
    			solve((a[i] + 1ll * j * b[i] % Q) % Q + 1,++num);
    
    	cout<<(ans % mod + mod) % mod;
    	return 0;
    }
    
  • 相关阅读:
    windows系统切换jdk,修改java_home无效情况
    Cannot instantiate interface org.springframework.context.ApplicationListener
    MySQL分组查询获取每个学生前n条分数记录(分组查询前n条记录)
    ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET
    EF TO MYSQL 无法查询中文的解决方法
    HttpWebRequest post请求获取webservice void数据信息
    This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分 解决方案
    MySQL 5.7.13解压版安装记录 mysql无法启动教程
    C# udpclient 发送数据断网后自动连接的方法
    汽车XX网站秒杀抢购代码
  • 原文地址:https://www.cnblogs.com/wxyww/p/vijos2051.html
Copyright © 2011-2022 走看看