题解:[NOIP2023] 天天爱打卡

题目传送门

\([l,r,w]\) 表示 \(l\sim r\) 每天都跑步,小 T 请用户吃饭造成的提高为 \(w\)

测试点 \(1\sim9\)

一个非常显然的 \(\mathcal O(nk)\) 的 DP。

\(\textit{dp}_{i,j}\) 为在第 \(i\)结束时连续打卡了 \(j\) 天的最大能量值。

则有:

\[\begin{aligned} \textit{dp}_{i,0}&=\max_{j=0}^{k}\textit{dp}_{i-1,j}\\ \textit{dp}_{i,j}&=\textit{dp}_{i-1,j-1}+\sum_{x_l=i\land j\geq y_l}v_l \end{aligned} \]

答案即 \(\max\limits_{i=0}^k\textit{dp}_{n,i}\)

期望得分:\(\text{36pts}\)

参考代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
constexpr const int N=1e3,K=N,M=1e5;
vector<pair<int,int> >a[N+1];
int n,m,k,d;
ll dp[N+1][K+1];
void Start(){
	for(int i=1;i<=n;i++){
		a[i].resize(0);
	}
	memset(dp,0,sizeof(dp));
}
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int c,T;
	cin>>c>>T;
	while(T--){
		Start();
		cin>>n>>m>>k>>d;
		for(int i=1;i<=m;i++){
			int x,y,v;
			cin>>x>>y>>v;
			a[x].push_back({y,v});
		}
		for(int i=1;i<=n;i++){
			dp[i][0]=dp[i-1][0];
			for(int j=1;j<=k;j++){
				dp[i][0]=max(dp[i][0],dp[i-1][j]);
			}
			for(int j=1;j<=k;j++){
				dp[i][j]=dp[i-1][j-1]-d;
				for(auto pl:a[i]){
					int &y=pl.first,&v=pl.second;
					if(j>=y){
						dp[i][j]+=v;
					}
				}
			}
		}
		ll ans=dp[n][0];
		for(int j=1;j<=k;j++){
			ans=max(ans,dp[n][j]);
		}
		cout<<ans<<'\n';
	}
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}

考虑优化上面的 DP,所以更改 DP 状态,因为 \(\mathcal O(1)\) 转移已经不能继续优化


测试点 \(1\sim7\)

\(\textit{dp}_{i,1},\textit{dp}_{i,0}\) 分别为第 \(i\) 天是否跑步的最大能量值。

则有:

\[\begin{aligned} \textit{dp}_{i,0}&=\max_{j=1}^{i-1}\textit{dp}_{j,1}=\max\left(\textit{dp}_{i-1,0},\textit{dp}_{i-1,1}\right)\\ \textit{dp}_{i,1}&=\max_{j=1}^{\min(i,k)}\left(\textit{dp}_{i-j,0}-j\cdot d+\operatorname{calc}(i-j+1,i)\right) \end{aligned} \]

其中,\(\operatorname{calc}(l,r)\) 表示 \(l\sim r\) 一直跑步增加的能量值,显然可以 \(\mathcal O(m)\) 计算。

于是得到了一个更劣的 \(\mathcal O(nmk)\) 的解法。将给定的 \([l_i,r_i]\) 按照 \(r_i\) 排序后单次计算 \(\operatorname{calc}(l,r)\) 时在给定区间上二分,可以减小常数。期望复杂度为 \(\mathcal O\left(nk\left(\log m+\dfrac mn\right)\right)=\mathcal O\left(nk\log m+mk\right)\)

期望得分 \(\text{28pts}\)

参考代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
constexpr const int N=1e5,K=N,M=1e5;
struct line{
	int l,r,w;
}a[M+1];
int n,m,k,d;
ll dp[N+1][2];
ll calc(int l,int r){
	ll ans=0;
	int L=0,R=m;
	while(L<R){
		int mid=L+R+1>>1;
		if(a[mid].r<=r){
			L=mid;
		}else{
			R=mid-1;
		}
	}
	for(int i=L;1<=i&&i<=m&&l<=a[i].r;i--){
		if(l<=a[i].l){
			ans+=a[i].w;
		}
	}
	return ans;
}
void Start(){
	memset(dp,0,sizeof(dp));
}
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int c,T;
	cin>>c>>T;
	while(T--){
		Start();
		cin>>n>>m>>k>>d;
		for(int i=1;i<=m;i++){
			int &l=a[i].l,&r=a[i].r,&w=a[i].w;
			int x,y;
			cin>>x>>y>>w;
			r=x;
			l=x-y+1;
		}
		sort(a+1,a+m+1,[](line a,line b){
			return a.r<b.r;
		});
//		for(int i=1;i<=m;i++){
//			cerr<<"["<<a[i].l<<","<<a[i].r<<"]:"<<a[i].w<<endl;
//		} 
		for(int i=1;i<=n;i++){
			dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
			dp[i][1]=dp[i-1][0]-d+calc(i,i);
			for(int j=2;j<=i&&j<=k;j++){
				dp[i][1]=max(dp[i][1],dp[i-j][0]-1ll*j*d+calc(i-j+1,i));
			}
		}
		cout<<max(dp[n][0],dp[n][1])<<'\n';
	}
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}

测试点 \(8\sim11\)

考虑优化上面的 DP。

发现 \(\operatorname{calc}(l,r)\) 具有的性质就是 \(r\) 单调递增。因此可以想到数据结构维护 \(l_i\) 处增加的 \(w_i\)

在 DP 之前将 \([l_i,r_i]\)\(r_i\) 排序,DP 时依次加入即可。设 \(\operatorname{query}(x)\) 表示 \(l_i\geq x\)\(w_i\) 之和。

则有:

\[\begin{aligned} \textit{dp}_{i,0}&=\max\left(\textit{dp}_{i-1,0},\textit{dp}_{i-1,1}\right)\\ \textit{dp}_{i,1}&=\max_{j=\max(i-k,0)}^{i-1}\left(\textit{dp}_{j,0}-(i-j)d+\operatorname{query}(j+1)\right) \end{aligned} \]

时间复杂度:\(\mathcal O((nk+m)\log m)\)。期望得分:\(\text{36pts}\)原地打转。

参考代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
constexpr const int N=1e5,K=N,M=1e5;
struct BIT{
	ll t[N+1];
	int tag[N+1],Tag;
	void clear(){
		Tag++;
	}
	int lowbit(int x){
		return x&-x;
	}
	ll query(int x){
		ll ans=0;
		while(x<=N){
			if(tag[x]!=Tag){
				t[x]=0;
				tag[x]=Tag;
			}
			ans+=t[x];
			x+=lowbit(x);
		}
		return ans;
	}
	void add(int x,int k){
		while(x){
			if(tag[x]!=Tag){
				t[x]=0;
				tag[x]=Tag;
			}
			t[x]+=k;
			x-=lowbit(x);
		}
	}
}t;
struct line{
	int l,r,w;
}a[M+1];
int n,m,k,d;
ll dp[N+1][2];
void Start(){
	t.clear();
	memset(dp,0,sizeof(dp));
}
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int c,T;
	cin>>c>>T;
	while(T--){
		Start();
		cin>>n>>m>>k>>d;
		for(int i=1;i<=m;i++){
			int &l=a[i].l,&r=a[i].r,&w=a[i].w;
			int x,y;
			cin>>x>>y>>w;
			r=x;
			l=x-y+1;
		}
		sort(a+1,a+m+1,[](line a,line b){
			if(a.r!=b.r){
				return a.r<b.r;
			}else{
				return a.l<b.l;
			}
		});
		for(int i=1,p=1;i<=n;i++){
			dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
			
			while(p<=m&&a[p].r<=i){
				t.add(a[p].l,a[p].w);
				p++;
			}
			
			dp[i][1]=-1ll<<60;
			for(int j=max(i-k,0);j<i;j++){
				dp[i][1]=max(dp[i][1],dp[j][0] - 1ll*(i-j)*d + t.query(j+1));
			}
		}
		cout<<max(dp[n][0],dp[n][1])<<'\n';
	}
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}

测试点 \(10\sim14\)

发现 \(\textit{dp}_{i,1}\) 的递推式其实是一个区间递推,因此可以考虑线段树优化 DP。

线段树维护 \(\textit{dp}_{j,0}\) 对于 DP 的贡献,即 \(\textit{dp}_{j,0}-(i-j)d+\operatorname{query}(j+1)\)

  • \(-(i-j)d\)\(i\) 变化时可以通过区间加法维护,在 \([0,i-1]\) 上减去 \(d\) 即可。
  • \(\operatorname{query}(j+1)\)\(i\) 变化时维护对应增加的 \([l,r,w]\),在线段树上的 \([0,l-1]\) 这段区间进行区间加法加 \(w\) 即可。
  • 查询只需要线段树维护区间 \([\max(i-k,0),i-1]\) 最大值即可。

时间复杂度:\(\mathcal O(n\log n+m\log m)\)。期望得分:\(\text{56pts}\)

参考代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
constexpr const ll inf=0x3f3f3f3f3f3f3f3f;
constexpr const int N=1e5,K=N,M=1e5;
struct line{
	int l,r,w;
}a[M+1];
struct segTree{
	struct node{
		int l,r;
		ll max,tag;
	}t[N<<2|1];
	
	void up(int p){
		t[p].max=max(t[p<<1].max,t[p<<1|1].max);
	}
	void build(int p,int l,int r){
		t[p].l=l,t[p].r=r;
		t[p].tag=0;
		if(l==r){
			t[p].max=0;
			return;
		}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		up(p);
	}
	void down(int p){
		if(t[p].tag){
			t[p<<1].max+=t[p].tag;
			t[p<<1].tag+=t[p].tag;
			t[p<<1|1].max+=t[p].tag;
			t[p<<1|1].tag+=t[p].tag;
			t[p].tag=0;
		}
	}
	void add(int p,int l,int r,ll k){
		if(l<=t[p].l&&t[p].r<=r){
			t[p].tag+=k;
			t[p].max+=k;
			return;
		}
		down(p);
		if(l<=t[p<<1].r){
			add(p<<1,l,r,k);
		}
		if(t[p<<1|1].l<=r){
			add(p<<1|1,l,r,k);
		}
		up(p);
	}
	ll query(int p,int l,int r){
		if(l<=t[p].l&&t[p].r<=r){
			return t[p].max;
		}
		down(p);
		ll ans=-inf;
		if(l<=t[p<<1].r){
			ans=query(p<<1,l,r);
		}
		if(t[p<<1|1].l<=r){
			ans=max(ans,query(p<<1|1,l,r));
		}
		return ans;
	}
}t;
int n,m,k,d;
ll dp[N+1][2];
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int c,T;
	cin>>c>>T;
	while(T--){
		cin>>n>>m>>k>>d;
		t.build(1,0,n);
		for(int i=1;i<=m;i++){
			int &l=a[i].l,&r=a[i].r,&w=a[i].w;
			int x,y;
			cin>>x>>y>>w;
			r=x;
			l=x-y+1;
		}
		sort(a+1,a+m+1,[](line a,line b){
			if(a.r!=b.r){
				return a.r<b.r;
			}else{
				return a.l<b.l;
			}
		});
		for(int i=1,p=1;i<=n;i++){
			dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
			t.add(1,i-1,i-1,dp[i-1][0]);
			while(p<=m&&a[p].r<=i){
				t.add(1,0,a[p].l-1,a[p].w);
				p++;
			}
			t.add(1,0,i-1,-d);
			dp[i][1]=t.query(1,max(i-k,0),i-1);
		}
		cout<<max(dp[n][0],dp[n][1])<<'\n';
	}
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}

测试点 \(15\sim25\)

考虑优化。

拆式子,得到:

\[\textit{dp}_{i,1}=\max_{j=\max(i-k,0)}^{i-1}\left(\textit{dp}_{j,0}+jd+\operatorname{query}(j+1)\right)-id \]

这样,就避免了 \(i\)\(j\) 的贡献的影响,\(j\) 的贡献即 \(\textit{dp}_{j,0}+jd+\operatorname{query}(j+1)\)。这是确定的,并且可以发现有效的决策点一定是 \(l-1\)\(r\)。那么离散化 \(l-1,r\),在 \(l-1,r\) 上决策即可。

操作可以在动态开点权值线段树上维护,但是被卡常了。Loj上有 \(\text{84pts}\)洛谷上只有 \(\text{60pts}\)

参考代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
namespace io {
	const int SIZE = (1 << 25) + 1;
	char ibuf[SIZE], *iS, *iT;
	char obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[64];
	int f, qr;
	
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	template <class I> inline void IN (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); 
		x = f == -1 ? -x : x;
	}
	template <class I> inline void print (I x) {
		if (! x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[ ++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr -- ]);
	}
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: IN;
using io :: putc;
using io :: print;
typedef long long ll;
constexpr const ll inf=0x3f3f3f3f3f3f3f3f;
constexpr const int N=1e9,K=N,M=1e5;
struct line{
	int l,r,w;
}a[M+1];
struct segTree{
	struct node{
		int l,r;
		ll max,tag;
		int lChild,rChild; 
	}t[M*(__lg(N+1)+1)*3];
	
	int size;
	inline void clear(){
		size=0;
	} 
	inline int create(int l,int r){
		size++;
		t[size]={l,r};
		return size;
	}
	inline void up(int p){
		t[p].max=max(t[t[p].lChild].max,t[t[p].rChild].max);
	}
	inline void down(int p){
		if(!t[p].lChild){
			t[p].lChild=create(t[p].l,t[p].l+t[p].r>>1);
		}
		t[t[p].lChild].max+=t[p].tag;
		t[t[p].lChild].tag+=t[p].tag;
		if(!t[p].rChild){
			t[p].rChild=create((t[p].l+t[p].r>>1)+1,t[p].r);
		}
		t[t[p].rChild].max+=t[p].tag;
		t[t[p].rChild].tag+=t[p].tag;
		t[p].tag=0;
	}
	void add(int p,int l,int r,ll k){
		if(l<=t[p].l&&t[p].r<=r){
			t[p].tag+=k;
			t[p].max+=k;
			return;
		}
		down(p);
		if(l<=t[t[p].lChild].r){
			add(t[p].lChild,l,r,k);
		}
		if(t[t[p].rChild].l<=r){
			add(t[p].rChild,l,r,k);
		}
		up(p);
	}
	ll query(int p,int l,int r){
		if(l<=t[p].l&&t[p].r<=r){
			return t[p].max;
		}
		down(p);
		ll ans=-inf;
		if(l<=t[t[p].lChild].r){
			ans=query(t[p].lChild,l,r);
		}
		if(t[t[p].rChild].l<=r){
			ans=max(ans,query(t[p].rChild,l,r));
		}
		return ans;
	}
}t;
int n,m,k,d;
ll dp[M*3+1][2];
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int c,T;
	IN(c);IN(T);
//	cin>>c>>T;
	while(T--){
		IN(n);IN(m);IN(k);IN(d);
//		cin>>n>>m>>k>>d;
		t.clear();
		t.create(0,n);
		static int tmp[M*3+1]; 
		int len=0;
		for(int i=1;i<=m;i++){
			int &l=a[i].l,&r=a[i].r,&w=a[i].w;
			int x,y;
			IN(x);IN(y);IN(w);
//			cin>>x>>y>>w;
			r=x;
			l=x-y+1;
			if(l-1){
				tmp[++len]=l-1;
			}
			tmp[++len]=r;
		}
		sort(tmp+1,tmp+len+1);
		len=unique(tmp+1,tmp+len+1)-tmp-1;
		sort(a+1,a+m+1,[](line a,line b){
			if(a.r!=b.r){
				return a.r<b.r;
			}else{
				return a.l<b.l;
			}
		});
		for(int i=1,p=1;i<=len;i++){
			dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
			t.add(1,tmp[i-1],tmp[i-1],dp[i-1][0] + 1ll*tmp[i-1]*d);
			while(p<=m&&a[p].r<=tmp[i]){
				t.add(1,0,a[p].l-1,a[p].w);
				p++;
			}
			dp[i][1]=t.query(1,max(tmp[i]-k,0),tmp[i]-1)-1ll*tmp[i]*d;
//			cerr<<"dp["<<setw(5)<<i<<"][0]="<<setw(12)<<dp[i][0]<<" "<<"dp["<<setw(5)<<i<<"][1]="<<setw(12)<<dp[i][1]; 
//			cerr<<"  r="<<setw(8)<<a[p-1].r<<endl;
		}
		print(max(dp[len][0],dp[len][1]));
		putc('\n');
//		cout<<max(dp[len][0],dp[len][1])<<'\n';
	}
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}

于是可以写普通线段树维护,时间复杂度 \(\mathcal O(m\log m)\)

AC 代码

//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll; 
constexpr const ll inf=0x3f3f3f3f3f3f3f3f;
constexpr const int N=1e9,K=N,M=1e5;
struct line{
	int l,r,w;
}a[M+1];
struct segTree{
	struct node{
		int l,r;
		ll max,tag;
	}t[M<<4|1];
	
	inline void up(int p){
		t[p].max=max(t[p<<1].max,t[p<<1|1].max);
	}
	void build(int p,int l,int r){
		t[p].l=l,t[p].r=r;
		t[p].tag=0;
		if(l==r){
			t[p].max=0;
			return;
		}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		up(p);
	}
	inline void down(int p){
		if(t[p].tag){
			t[p<<1].max+=t[p].tag;
			t[p<<1].tag+=t[p].tag;
			t[p<<1|1].max+=t[p].tag;
			t[p<<1|1].tag+=t[p].tag;
			t[p].tag=0;
		}
	}
	void add(int p,int l,int r,ll k){
		if(l<=t[p].l&&t[p].r<=r){
			t[p].tag+=k;
			t[p].max+=k;
			return;
		}
		down(p);
		if(l<=t[p<<1].r){
			add(p<<1,l,r,k);
		}
		if(t[p<<1|1].l<=r){
			add(p<<1|1,l,r,k);
		}
		up(p);
	}
	ll query(int p,int l,int r){
		if(l<=t[p].l&&t[p].r<=r){
			return t[p].max;
		}
		down(p);
		ll ans=-inf;
		if(l<=t[p<<1].r){
			ans=query(p<<1,l,r);
		}
		if(t[p<<1|1].l<=r){
			ans=max(ans,query(p<<1|1,l,r));
		}
		return ans;
	}
}t;
int n,m,k,d;
ll dp[M<<1|1][2];
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int c,T;
	cin>>c>>T;
	while(T--){
		cin>>n>>m>>k>>d;
		t.build(1,0,m<<1);
		static int tmp[M<<1|1]; 
		int len=0;
		for(int i=1;i<=m;i++){
			int &l=a[i].l,&r=a[i].r,&w=a[i].w;
			int x,y;
			cin>>x>>y>>w;
			r=x;
			l=x-y/*+1*/;
			tmp[++len]=l;
			tmp[++len]=r;
		}
		sort(tmp+1,tmp+len+1);
		len=unique(tmp+1,tmp+len+1)-tmp-1;
		for(int i=1;i<=m;i++){
			a[i].l=lower_bound(tmp+1,tmp+len+1,a[i].l)-tmp;
			a[i].r=lower_bound(tmp+1,tmp+len+1,a[i].r)-tmp;
		}
		sort(a+1,a+m+1,[](line a,line b){
			if(a.r!=b.r){
				return a.r<b.r;
			}else{
				return a.l<b.l;
			}
		});
		for(int i=1,p=1,last=0;i<=len;i++){
			dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
			t.add(1,i-1,i-1,dp[i-1][0] + 1ll*tmp[i-1]*d);
			while(p<=m&&a[p].r<=i){
				t.add(1,0,a[p].l,a[p].w);
				p++;
			}
			while(tmp[last]<tmp[i]-k){
				last++;
			}
			dp[i][1]=t.query(1,last,i-1)-1ll*tmp[i]*d;
		}
		cout<<max(dp[len][0],dp[len][1])<<'\n';
	}
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}
posted @ 2025-08-06 15:42  TH911  阅读(15)  评论(0)    收藏  举报