首页 > 其他分享 >【题解】Luogu P4340 [SHOI2016] 随机序列

【题解】Luogu P4340 [SHOI2016] 随机序列

时间:2025-01-21 14:54:04浏览次数:1  
标签:res int 题解 mid P4340 il Luogu rid id

简单手摸后发现,答案就是这么一个式子:

\[(3^{n-1}-3^{n-2})a_1+(3^{n-2}-3^{n-3})a_1a_2+\dots+(3^1-3^0)a_1a_2\dots a_{n-1}+a_1a_2\dots a_n \]

啊当然证明也是好证的,对于 \(a_1\) 这一项,它后面放 +- 都会对系数加一,而放 * 不会影响系数,因此系数就是总数的三分之二。其它前缀乘积的系数都是类似的算法。

然后为什么没有别的项了呢?可以认为 * 不产生贡献,而 +- 是相同数量的,因此都消掉了。

简单预处理,修改时取逆元区间乘就行了。

但其实不行,因为输入的是非负数,而不是正整数,而 \(0\) 是没逆元的。

观察式子,发现从第一个 \(0\) 往后的项就都是 \(0\) 了。因此可以用一个 set 来维护 \(0\) 的位置。操作时正常操作,把 \(0\) 当成 \(1\) 就行了。查询时只查 \(1\) 到第一个 \(0\) 的位置前面。

#include<bits/stdc++.h>
#define ll long long
#define il inline
#define read(x){\
	char ch;\
	int fu=1;\
	while(!isdigit(ch=getchar()))\
		fu-=(ch=='-')<<1;\
	x=ch&15;\
	while(isdigit(ch=getchar()))\
		x=(x<<1)+(x<<3)+(ch&15);\
	x*=fu;\
}
#define lid id<<1
#define rid id<<1|1
using namespace std;
namespace asbt{
namespace cplx{bool begin;}
const int maxn=1e5+5,mod=1e9+7;
int n,m,a[maxn],b[maxn],pw3[maxn];
int sum[maxn<<2],tag[maxn<<2];
il void pushup(int id){
	sum[id]=(sum[lid]+sum[rid])%mod;
}
il void pushtag(int id,int val){
	tag[id]=tag[id]*1ll*val%mod;
	sum[id]=sum[id]*1ll*val%mod;
}
il void pushdown(int id){
	if(tag[id]>1){
		pushtag(lid,tag[id]);
		pushtag(rid,tag[id]);
		tag[id]=1;
	}
}
il void build(int id,int l,int r){
	tag[id]=1;
	if(l==r){
		sum[id]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(lid,l,mid);
	build(rid,mid+1,r);
	pushup(id);
}
il void upd(int id,int L,int R,int l,int r,int val){
	if(L>=l&&R<=r){
		pushtag(id,val);
		return ;
	}
	pushdown(id);
	int mid=(L+R)>>1;
	if(l<=mid){
		upd(lid,L,mid,l,r,val);
	}
	if(r>mid){
		upd(rid,mid+1,R,l,r,val);
	}
	pushup(id);
}
il int query(int id,int L,int R,int l,int r){
	if(L>=l&&R<=r){
		return sum[id];
	}
	pushdown(id);
	int mid=(L+R)>>1,res=0;
	if(l<=mid){
		(res+=query(lid,L,mid,l,r))%=mod;
	}
	if(r>mid){
		(res+=query(rid,mid+1,R,l,r))%=mod;
	}
	return res;
}
il void debug(int id,int l,int r){
	cout<<id<<" "<<l<<" "<<r<<" "<<sum[id]<<"\n";
	if(l==r){
		return ;
	}
	pushdown(id);
	int mid=(l+r)>>1;
	debug(lid,l,mid);
	debug(rid,mid+1,r);
}
il int qpow(int x,int y){
	int res=1;
	while(y){
		if(y&1){
			res=res*1ll*x%mod;
		}
		x=x*1ll*x%mod,y>>=1;
	}
	return res;
}
set<int> zero;
namespace cplx{
	bool end;
	il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
	read(n)read(m);
	pw3[0]=1;
	for(int i=1;i<=n;i++){
		read(a[i]);
		if(!a[i]){
			a[i]=1;
			zero.insert(i);
		}
		b[i]=a[i];
		pw3[i]=pw3[i-1]*3ll%mod;
	}
	zero.insert(n+1);
	for(int i=n;i;i--){
		(pw3[i]+=mod-pw3[i-1])%=mod;
	}
	for(int i=2;i<=n;i++){
		a[i]=a[i]*1ll*a[i-1]%mod;
	}
	for(int i=1;i<=n;i++){
		a[i]=a[i]*1ll*pw3[n-i]%mod;
	}
	build(1,1,n);
	while(m--){
		int pos,val;
		read(pos)read(val);
		zero.erase(pos);
		if(!val){
			val=1,zero.insert(pos);
		}
		upd(1,1,n,pos,n,val*1ll*qpow(b[pos],mod-2)%mod);
		b[pos]=val;
		printf("%d\n",*zero.begin()==1?0:query(1,1,n,1,*zero.begin()-1));
	}
	return 0;
}
}
int main(){return asbt::main();}
/*
4 1
1 2 3 4
1 2
*/

标签:res,int,题解,mid,P4340,il,Luogu,rid,id
From: https://www.cnblogs.com/zhangxyhp/p/18683588

相关文章

  • 题解:P3823 [NOI2017] 蚯蚓排队
    题目链接https://www.luogu.com.cn/problem/P3823分析先解决队伍的合并与分离问题。使用链表结构,分别维护每只蚯蚓的前驱和后继即可。然后考虑如何统计答案。可以对每只蚯蚓的“向后\(k\)数字串”使用字符串哈希的方式获得哈希值,再用一个哈希表存储每个哈希值出现的次数。对......
  • 2024 (ICPC) Jiangxi Provincial Contest I 题 Neuvillette Circling题解
    简单思路一个圆套中了几个点,如果不断缩小这个圆,那么最终的结果有两种有两个点卡住了这个圆,且这两点一定是直径有三个或者三个以上的点卡住了这个圆,圆心在这三个点围成的三角形的外接圆圆心。因此我们枚举两点作为直径,或者枚举三个点作为圆的内接三角形,求这个三角形的外接圆......
  • 2024 (ICPC) Jiangxi Provincial Contest L 题 Campus 题解
    简单思路首先对于所有的出口求一遍最短路,由于出口只会打开并关闭一次,所以大门的开启状态是相当有限的(最多大概30种),我们对于每一种状态直接暴力求答案最后输出即可。复杂度大概\(O(knlogn)\)参考代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;type......
  • Codeforces Round 998 (Div. 3) 部分题解
    写题解的时候这场在评测,就不放代码了。E.GraphComposition题意给两个无向简单图,对图\(1\)添加若干条边或删除若干条边,使得两图的连通性一致,最少需要变更多少条边。题解求出图\(2\)的连通性,考虑图\(1\)的所有边,若违背了图\(2\)联通性的要删除(图\(2\)不联通但图\(......
  • 20250120 T2 simu题解
    简单模拟(simu)【题目描述】给定$a_1,a_2,\ldots,a_n$和$b_1,b_2,\ldots,b_n$。对于所有整数$x\in[l,r]$,模拟以下过程并求出变量$res$的最终的值。res=0fori=1ton:ifx>=a[i]:x=x-a[i]res=res+b[i]【输入格式】......
  • 「题解」二进制与一
    传送门:水滴、洛谷题目大意:给定一个正整数$n$,给出操作次数$p$。每次操作让$n$加上一个非负整数$x$,使得$n$的第$k$位为$0$(从右往左数)。如果本身为$1$就不用操作。且每次操作$n+x$回影响后续操作。问$x$的和是多少。首先我们要知道,判断$n$的第$k$位是否为$......
  • 题解:CF580B Kefa and Company
    CF580BKefaandCompany前言。其实本题与这道题极为相似,所以建议降橙。思路因为输入顺序不影响就结果,所以可以先给\(a\)按照工资从小到打排序一下序(这里\(a\)使用MAP)。然后再使用尺取法,只要\(a_{r+1}\)的值减\(a_l\)的值\(\ltk\)就将\(r\)加\(1\)。然后发现每......
  • [BZOJ3160] 万径人踪灭 题解
    首先正难则反,想到答案即为满足第一条要求的回文子序列数量,减去回文子串数量。回文子串数量\(hash+\)二分即可,考虑前半部分。假如我们将一个回文子序列一层层剥开,就会发现它其实是由多个相同的字母对拼成的。那么容易想到把字母\(a\)和字母\(b\)的贡献分开计算。那第一条要......
  • PKUWC 2025 题解
    本人太菜,实在不会T3,所以只有T1,T2的题解。注:考场上只做出来了Day1T1,其他题参考了其他人的题解。Day1T1电池检测题面有\(a\)个有电的电池和\(b\)个没电的电池,每次只能选择两个电池放进手电筒,只有这两个电池全有电才能让手电筒启动。问最坏情况下最少可以让手电筒启......
  • AT_abc389_f [ABC389F] Rated Range 题解
    题目传送门前置知识Treap|线段树解法考虑将询问的\(x\)离线下来在升序排序后一起处理。观察到每次操作只有\(+1\),即其之间的相对大小关系不会发生变化,此时就只需要支持将值在\([l,r]\)内的数加一,可以记录懒惰标记。线段树上二分找到端点或直接FHQ-Treap分裂出合法......