雨水从黑云降临到了人间 果实脱落枝叶吸收于地面 时间流逝再也回不到从前 曾经珍藏回忆变成不可逆爱恋

test42

lgj 咬打火机。

萌熊比赛都来了 /fad


寻雾启示

首先最终的走法一定是找到位置序列 \(p_1,\dots,p_m\) 满足 \(p_i<p_{i+1},p_m=n\) 然后依次铺羊毛到 \(p_i\),为了不思考那么多,我们设 \(f_i\) 表示铺到 \(i\) 回到 \(1\) 的最小时间,转移显然是 \(f_i=\min\{\max(f_j,ik)+2t_1j+(i-j)(t_1+t_2)\}\),没有除了最开始那个 \(\max\{f_j,ik\}\) 没有 \(i,j\) 复合的项,独立出来看作常数,然后 \(f_j\) 显然 \(\uparrow\),所以我们可以双指针扫出两种贡献的区间,前面那个前缀 \(\max\),后面那个用 multiset 找出最大常数。

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

const int N=100005, inf=1e18;

int T, m, k, t1, t2, f[N];

void mian() {
	cin >> m >> k >> t1 >> t2, t1+=t2;
	int j=1, ran=0;
	multiset<int> coel;
	coel.insert(inf);
	up(i,1,m) {
		while(j<i&&f[j]<i*k) {
			coel.erase(coel.find(f[j]+(2*t2-t1)*j));
			ran=min(ran,(2*t2-t1)*j++);
		}
		f[i]=min(ran+i*k,*coel.begin())+i*t1;
		coel.insert(f[i]+(2*t2-t1)*i);
		cout << f[i]-t2*i << ' ';
	}
	cout << '\n';
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> T;
	while(T--) mian();
	return 0;
}

青年晚报

题面写的真的好恶心。

首先发现 \(f/g\) 贡献独立,当成俩问题,自己多抄写几次,然后把算式组合意义一下,可以看作每个点有一个 \([0,m]\) 的初始等级,每次可以直接 \(\times 1\) 走到下一层,或者根据层数的 \(\text{odd/eve}\) 下降等级 \(\times (+/-)rk\) 走向下一层,注意等级始终在 \([0,m]\)

那我们想想怎么考虑 \(f_i\to (F/G)_j\) 的贡献,首先 \(j\leq i\),等级下降绝对值系数有一个 \(\frac{i!}{j!}\),然后还想知道选择下降位置的系数,这个容易预处理出来,枚举走 \(l/r\)\(+/1\) 用组合数乘正负然后贡献给 \(dp_{l+r}\) 即可。

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

const int N=5005, P=1e9+7;

int n, m, f[N], g[N], F[N], G[N], mul[N], inv[N];
int l[N], r[N], sav[2][N];

inline int C(int x,int y) {
	if(y<0||x<y) return 0;
	int u=x-n/2, val=1;
	if(sav[u][y]) return sav[u][y];
	up(i,x-y+1,x) val=val*i%P;
	up(i,1,y) val=val*inv[i]%P;
	return sav[u][y]=val;
}

inline void add(int &a,int b) { a=(a+b)%P; }

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	mul[0]=inv[0]=inv[1]=1;
	up(i,1,5000) mul[i]=mul[i-1]*i%P;
	up(i,2,5000) inv[i]=inv[P%i]*(P-P/i)%P;
	cin >> n >> m;
	up(i,0,m) cin >> f[i];
	up(i,0,m) cin >> g[i];
	up(i,0,m) {
		int L=n/2+(n%2==1), R=n/2;
		up(j,0,i) add(l[i],C(L,j)*C(R,i-j)%P*(j%2==0?1:-1));
	}
	up(i,0,m) {
		int L=n/2, R=n/2+(n%2==1);
		up(j,0,i) add(r[i],C(L,j)*C(R,i-j)%P*(j%2==0?1:-1));
	}
	up(i,2,5000) inv[i]=inv[i-1]*inv[i]%P;
	up(i,0,m) up(j,0,i) {
		int v=l[j]*mul[i]%P*inv[i-j]%P*f[i]%P;
		if(n%2==0) add(F[i-j],v); else add(G[i-j],v);
	}
	up(i,0,m) up(j,0,i) {
		int v=r[j]*mul[i]%P*inv[i-j]%P*g[i]%P;
		if(n%2==0) add(G[i-j],v); else add(F[i-j],v);
	}
	up(i,0,m) cout << (F[i]%P+P)%P << ' '; cout << '\n';
	up(i,0,m) cout << (G[i]%P+P)%P << ' '; cout << '\n';
	return 0;
}

寻宝游戏

如果 \(l+1=r\),那么必须同时操作俩,如果是 \(1,1\) 需要 \(1\) 次,如果是 \(1,2\) 答案是 \(-1\),别的都会变成 \(len=3\) 的问题,我们只用下面考虑 \(len\geq 3\) 的怎么做(虽然我写代码的时候很蠢地对这个进行了分类讨论)。

我们希望把所有的泡面扔到一个目标桶里面,我们分类考虑一下,首先目标桶一定是最大的 \((\text{odd/eve})a_i\),设去掉这个桶之后最大的桶有 \(sec\) 桶、总和为 \(sum\)

  • \(2|sum\),理想型。
  1. \(sec\leq sum-sec\),那么 \(\frac{sum}{2}\) 次得了。
  2. \(sec>sum-sec\),那么 \(sec\) 是下界,并且操作 \(sec\) 次是可以做到的,\(sec-\frac{sum}{2}+\frac{sum}{2}\) 说是。
  • \(2\nmid sum\),不算理想(?

    此时必须调整目标桶,不然奇偶性永远对不上,然后就变成上面那种了喵 >w<

#pragma GCC optimize(1,2,3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

const int N=300005, M=21, inf=1e18;

int Pluto, n, T, q, a[N], s[N], odd[N][M], eve[N][M], fc[N], lg[N];

inline int Odd(int l,int r) {
	if(l>r) return 0;
	int k=lg[r-l+1], x=odd[l][k], y=odd[r-(1<<k)+1][k];
	return a[x]>a[y]?x:y;
}

inline int Eve(int l,int r) {
	if(l>r) return 0;
	int k=lg[r-l+1], x=eve[l][k], y=eve[r-(1<<k)+1][k];
	return a[x]>a[y]?x:y;
}

int ran(vector<int> sav) {
	int res=0;
	for(int u:sav) if(a[u]>a[res]) res=u;
	return res;
}

void mian() {
	cin >> n >> q, T=log2(n);
	up(i,1,n) {
		cin >> a[i];
		fc[i]=fc[i-1]+(a[i]==1);
		s[i]=s[i-1]+a[i];
		odd[i][0]=(a[i]%2==1?i:0);
		eve[i][0]=(a[i]%2==0?i:0);
	}
	up(j,1,T) up(i,1,n-(1<<j)+1) {
		int x=odd[i][j-1], y=odd[i+(1<<j-1)][j-1];
		odd[i][j]=(a[x]>a[y]?x:y);
	} 
	up(j,1,T) up(i,1,n-(1<<j)+1) {
		int x=eve[i][j-1], y=eve[i+(1<<j-1)][j-1];
		eve[i][j]=(a[x]>a[y]?x:y);
	}
	while(q--) {
		int l, r, p, sum, sec, ans=inf;
		cin >> l >> r;
		if(l==r) { cout << 0 << '\n'; continue; }
		if(fc[r]-fc[l-1]==r-l+1) { cout << (r-l+1)/2 << '\n'; continue; }
		if(l+1==r) {
			l=a[l], r=a[r];
			if(r<l) swap(l,r);
			if(l==1) {
				if(r==1) { cout << 1 << '\n'; continue; }
				if(r==2) { cout << -1 << '\n'; continue; }
				p=r-2;
				if(p==1) cout << 3 << '\n';
				if(p==2) cout << 4 << '\n';
				if(p>2) cout << 5 << '\n'; 
			}
			else {
				--l, --r;
				if(l==1) {
					if(r==1) cout << 2 << '\n';
					if(r==2) cout << 3 << '\n';
					if(r>2) cout << 4 << '\n';
					continue;
				}
				if(l==2) { cout << 3 << '\n'; continue; }
				if(l==r) { cout << l+1 << '\n'; continue; }
				if(l%2==1) cout << 2+max(l-1,(l+3)/2) << '\n';
				else cout << 1+max(l,(l+2)/2) << '\n';
			}
			continue;
		}
		if(p=Odd(l,r)) {
			sum=s[r]-s[l-1]-a[p];
			sec=a[ran({Odd(l,p-1),Eve(l,p-1),Odd(p+1,r),Eve(p+1,r)})];
			int res=max(sum/2,sec);
			if(sum%2==1) res=max((sum+1)/2,sec-1)+1;
			ans=min(ans,res);
		}
		if(p=Eve(l,r)) {
			sum=s[r]-s[l-1]-a[p];
			sec=a[ran({Odd(l,p-1),Eve(l,p-1),Odd(p+1,r),Eve(p+1,r)})];
			int res=max(sum/2,sec);
			if(sum%2==1) res=max((sum+1)/2,sec-1)+1;
			ans=min(ans,res);
		}
		cout << ans << '\n';
	}
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	up(i,1,3e5) lg[i]=log2(i);
	cin >> Pluto;
	while(Pluto--) mian();
	return 0;
}
posted @ 2025-11-19 20:01  Hypoxia571  阅读(11)  评论(0)    收藏  举报