ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

20210824 Prime,Sequence,Omeed

2021-08-25 08:35:05  阅读:158  来源: 互联网

标签:Prime return Sequence int res LL Omeed DP mod


考场

T1 貌似是 luogu 上原题
T2 计数,想起了这题这题,但没有 \(n^2\) 一档的分。。。准备打个表
T3 期望 DP,但暴力是 \(O(qn)\) 的,发现 \(combo\) 的形式像一次函数,应该要用 DS 维护。

7.30 开写,8.00 拍上 T1
T2 打表发现填的数是每个数最后一次出现位置的升序那就有 53pts,比较满意。然后一直在想怎么改上面那题的方程,弃的比较早
T3 一度推出的暴力 DP 的式子,写出来不对,调了调也没啥思路,只能拼部分分了。sub6 只要维护 \(p\) 的区间和就行了,sub4 应该是 DP 的弱化版,但求稳拍了一下 sub6

res

rk3 100+53+40

rk1 张泽阳 100+78+89
rk2 ycx 100+78+64

总结

想正解的时间太长,这两天都出现了会的部分分没时间写的情况。总想 A 题,但思路不够灵活,码力不够强,于是考得好不好完全取决与题适不适合我。。。其实没有必要 A 题,上次如果再拿一个 sub 也能 rk1,这次的前两名也都是靠部分分。
最近减少开写前想题的时间,但写完暴力再想也不太有用,再试试吧。

还有 DP 这个大坑。其实 DP 题做的也不少了,但还是做不出来/有想法调不出来,主要是抄题解太多了,很多东西没有自己思考,作死啊。发现每日一题咕的越来越多,题也越来越水了。。。等回去了重开一个吧,只记录紫题及以上。
另一方面,DP 弱已经成了心理上的束缚。T2 宁愿在以前题的基础上改也不愿意再想一个,T3 都写出来了也不愿意调。与其说能力不够,不如说自己已经认了,不相信自己能写出 DP,这和等死有什么区别,尽快调整心态。

Prime

线性筛出 \(\sqrt R\) 范围内质数,再埃氏筛 \([L,R]\) 中的,时间复杂度 \(O(\sqrt R+(R-L)\log\log R)\)

考场代码
const int N = 1e7+5;
int k;
LL l,r;

int n,pri,p[N];
LL ans;
bool vis[N];

void sieve() {
	For(i,2,n) {
		if( !vis[i] ) p[++pri] = i;
		for(int j = 1; j <= pri && i*p[j] <= n; ++j) {
			vis[i*p[j]] = 1;
			if( !(i % p[j]) ) break;
		}
	}
	memset(vis,0,sizeof vis);
}

signed main() {
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	read(l,r,k); n = min((int)sqrt(r),k);
	sieve();
	For(i,1,pri) for(LL j = max((LL)p[i],(l+p[i]-1)/p[i])*p[i]; j <= r; j += p[i])
		vis[j-l] = 1;
	for(LL i = l; i <= r; ++i) if( !vis[i-l] ) ans ^= i;
	write(ans);
	return iocl();
}

Sequence

考虑已经确定的数列如何 DP,设 \(f[i,j]\) 为前 \(i\) 个数以值 \(j\) 结尾的本质不同子序列,则 \(f[i,a_i]=1+\sum_{j=1}^kf[i-1,j],\forall j\neq a_i,f[i,j]=f[i-1,j]\)(将前面本质不同的子序列后加上 \(a_i\) 这个值,同时 \(a_i\) 单个值也算一个序列。答案为 \(\sum_{i=1}^kf[n,i]\)
发现将第一位滚掉后,不论 \(a_i\) 是什么,\(f[a_i]\) 的值是固定的,容易想到让 \(a_i\) 为当前 DP 值最小的值,即最后一次出现位置最靠前的值(DP 值一定不降)。那么后面 \(m\) 个元素填的顺序是固定的,每 \(k\) 个循环一次,矩阵快速幂加速递推即可。
时间复杂度 \(O(n+k^3\log m)\)

code
const int N = 1e6+5, mod = 1e9+7;
int n,k,a[N];
LL m;

LL sum=1,ans,f[105];
PII lst[105];

void ckadd(LL &x,LL y) { x+=y; if(x>=mod)x-=mod; else if(x<0)x+=mod; }

struct Mat {
	LL a[102][102];
	Mat(bool op=0) {
		memset(a,0,sizeof a);
		if(op) For(i,1,101) a[i][i] = 1;
	}
	LL* operator [] (int i) { return a[i]; }
} s,base,t;
Mat operator * (Mat x,Mat y) {
	Mat res;
	For(i,1,101) For(k,1,101) For(j,1,101) res[i][j] += x[i][k]*y[k][j] %mod;
	For(i,1,101) For(j,1,101) res[i][j] %= mod;
	return res;
}
Mat operator ^ (Mat x,LL y)
	{ Mat res(1); for(;y;y>>=1,x=x*x)if(y&1)res=res*x; return res; }

signed main() {
	read(n,m,k);
	For(i,1,n) read(a[i]), lst[a[i]].fi = i;
	For(i,1,k) lst[i].se = i; sort(lst+1,lst+k+1);
	For(i,1,n) {
		LL tmp = f[a[i]];
		f[a[i]] = sum, ckadd(sum,f[a[i]]-tmp);
	}
	For(i,1,k) s[1][i] = f[lst[i].se]; s[1][k+1] = 1;
	For(j,2,k) base[j][j-1] = 1; For(i,1,k+1) base[i][k] = 1; base[k+1][k+1] = 1;
	t = s * (base ^ m);
	For(i,1,k) ans += t[1][i];
	write(ans%mod);
	return iocl();
}

Omeed

\(BasicScore\) 显然是 \(\sum_{i=l}^rp_i\)。考虑暴力 DP :设 \(f[i]\) 为前 \(i\) 个音符的 \(Combo\),则有 \(f[i]=p_i(f[i+1]+1)+(1-p_i)t\times f[i-1]\),这部分的答案为 \(B\sum_{i=l+1}^rp_i(f[i-1]+1)\)。(因为只有当前这位 \(s_i=1\) 时 \(Combo\) 才有贡献,因此不能直接用 \(p_if[i]\) 算)
推推式子发现这是个一次函数的形式,线段树维护系数和常数即可(具体看代码)。

code
const int N = 5e5+5, mod = 998244353;
int sub,n,q;
LL tt,a,b;

LL Pow(LL x,LL y=mod-2)
	{ LL res=1; for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod; return res; }
LL frac(LL x,LL y) { return x * Pow(y) %mod; }

#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define up(u) (t[u]=t[ls]+t[rs])
struct Node {
	LL k,b,sumk,sumb,sump;
	// f[r]=kf[l-1]+b 这个区间的答案(f之和)为sumkf[l-1]+sumb p的区间和sump
	void init(LL x) { k = (x+tt-tt*x%mod+mod)%mod, b = sumk = sumb = sump = x; }
} t[N*4];
Node operator + (Node x,Node y) {
	return Node{ x.k*y.k%mod, (y.k*x.b+y.b)%mod,
				 (x.sumk+x.k*y.sumk)%mod, (x.sumb+y.sumk*x.b+y.sumb)%mod,
				 (x.sump+y.sump)%mod };
}
void build(int u=1,int l=1,int r=n) {
	if( l == r ) {
		LL x,y; read(x,y);
		return t[u].init(frac(x,y));
	}
	build(lson), build(rson);
	up(u);
}
void modify(int p,LL x,int u=1,int l=1,int r=n) {
	if( l == r ) return t[u].init(x);
	if( p <= mid ) modify(p,x,lson);
	else modify(p,x,rson);
	up(u);
}
Node query(int ql,int qr,int u=1,int l=1,int r=n) {
	if( ql <= l && r <= qr ) return t[u];
	if( qr <= mid ) return query(ql,qr,lson);
	if( mid < ql ) return query(ql,qr,rson);
	return query(ql,qr,lson) + query(ql,qr,rson);
}
#undef ls
#undef rs
#undef mid
#undef lson
#undef rson
#undef up

signed main() {
	read(sub,n,q,a,b); tt = frac(a,b); read(a,b);
	build();
	while( q-- ) {
		int op; read(op);
		if( !op ) {
			int u; LL x,y; read(u,x,y);
			modify(u,frac(x,y));
		} else {
			int l,r; read(l,r);
			Node ans = query(l,r);
			write((a*ans.sump + b*ans.sumb) %mod);
		}
	}
	return iocl();
}

标签:Prime,return,Sequence,int,res,LL,Omeed,DP,mod
来源: https://www.cnblogs.com/401rk8/p/noip0824.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有