冲刺CSP联训模拟2

冲刺CSP联训模拟2

题目来源:正睿 \(noip2023\) 赛前 \(20\) 天冲刺集训 \(day16(2023.11.2)\)

\(T1\) P294. 挤压 \(40pts\)

  • 部分分

    • \(20 \%\) :爆搜,时间复杂度为 \(O(2^{n})\)
    • 另外 \(20 \%\) :观察到值域较小,将值域计入状态设计,时间复杂度为 \(O(nV)\)
    点击查看代码
    const ll mod=1000000007;
    ll a[100010],p[100010],pp[100010],q[100010],f[2][9000010],ans=0;
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		b>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    void dfs(ll pos,ll n,ll sum,ll mul)
    {
    	if(pos==n+1)
    	{
    		sum%=mod;
    		ans=(ans+(sum*sum%mod)*mul%mod)%mod;
    	}
    	else
    	{
    		dfs(pos+1,n,sum^a[pos],mul*p[pos]%mod);
    		dfs(pos+1,n,sum,mul*pp[pos]%mod);
    	}
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,m=0,inv=qpow(1000000000,mod-2,mod),i,j;
    	cin>>n;
    	for(i=1;i<=n;i++)
    	{
    		cin>>a[i];
    		m=max(m,a[i]);
    	}
    	for(i=1;i<=n;i++)
    	{
    		cin>>q[i];
    		p[i]=q[i]*inv%mod;
    		pp[i]=(1000000000-q[i])*inv%mod;
    	}
    	if(n<=28)
    	{
    		dfs(1,n,0,1);
    	}
    	else
    	{
    		m*=2;
    		f[0][0]=1;
    		for(i=1;i<=n;i++)
    		{
    			for(j=0;j<=m;j++)
    			{
    				f[i&1][j]=(f[(i-1)&1][j]*pp[i]%mod+f[(i-1)&1][j^a[i]]*p[i]%mod)%mod;
    			}
    		}
    		for(i=0;i<=m;i++)
    		{
    			ans=(ans+((i%mod)*(i%mod)%mod)*f[n&1][i]%mod)%mod;
    		}
    	}
    	cout<<ans<<endl;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 正解

    • 按位做,考虑拆平方。
    • 设最终的异或和在二进制表示下(空位补零)为 \((s_{32}s_{31} \dots s_{1}s_{0})_{2}\) ,其平方可以表示成 \(\sum\limits_{i=0}^{32}\sum\limits_{j=0}^{32}s_{i}s_{j}2^{i+j}\)
    • 观察到每一项仅与两位有关,那么可以将 \(a_{x}\) 的第 \(i,j\) 位拿出来单独计算其期望。
    • \(f_{k,i,j,0/1,0/1}\) 表示处理到第 \(k\) 个数时,第 \(i\)\(=0/1\) 且第 \(j\)\(=0/1\) 的期望,枚举选或不选转移即可。
    • 最终,有 \(\sum\limits_{i=0}^{32}\sum\limits_{j=0}^{32}f_{n,i,j,1,1}2^{i+j}\) 即为所求。
    点击查看代码
    const ll mod=1000000007;
    ll a[100010],p[100010],q[100010],f[2][35][35][2][2];
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		b>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,inv=qpow(1000000000,mod-2,mod),ans=0,i,j,k,h,l;
    	cin>>n;
    	for(i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	for(i=1;i<=n;i++)
    	{
    		cin>>q[i];
    		p[i]=q[i]*inv%mod;
    	}
    	for(i=0;i<=32;i++)
    	{
    		for(j=0;j<=32;j++)
    		{
    			f[0][i][j][0][0]=1;
    		}
    	}
    	for(k=1;k<=n;k++)
    	{
    		for(i=0;i<=32;i++)
    		{
    			for(j=0;j<=32;j++)
    			{
    				for(h=0;h<=1;h++)
    				{
    					for(l=0;l<=1;l++)
    					{
    						f[k&1][i][j][h][l]=(f[(k-1)&1][i][j][h][l]*(1-p[k]+mod)%mod+f[(k-1)&1][i][j][h^((a[k]>>i)&1)][l^((a[k]>>j)&1)]*p[k]%mod);
    					}
    				}
    			}
    		}
    	}
    	for(i=0;i<=32;i++)
    	{
    		for(j=0;j<=32;j++)
    		{
    			ans=(ans+f[n&1][i][j][1][1]*qpow(2,i+j,mod)%mod)%mod;
    		}
    	}
    	cout<<ans<<endl;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

\(T2\) P295. 工地难题 \(25pts\)

  • 弱化版: Gym103428M 810975

    • 需要特判 \(k \le m \le n\) 时才可能存在解,当 \(k=0\) 时输出 \((m=0)\)
  • \(n \ne m\) 时,对于 \(k> \frac{m}{2}\) ,答案显然为 \(2\dbinom{n-(k+1)}{m-k}+\dbinom{n-(k+2)}{m-k}A_{n-(k+2)+1}^{1}=2\dbinom{n-k-1}{m-k}+\dbinom{n-k-2}{m-k}(n-k-1)\)

  • 部分分

    • \(20 \%\) :爆搜,递归枚举组合,并及时剪枝。
    点击查看代码
    const ll p=1000000007;
    ll inv[200010],jc[200010],jc_inv[200010],f[200010];
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		b>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    ll C(ll n,ll m,ll p)
    {
    	return (n>=m&&n>=0&&m>=0)?(jc[n]*jc_inv[n-m]%p)*jc_inv[m]%p:0;
    }
    void dfs(ll pos,ll n,ll sum0,ll sum1,ll maxx,ll pre,ll k)
    {
    	maxx=max(maxx,pre);
    	if(maxx<=k)
    	{
    		if(pos==n+1)
    		{
    			f[maxx]=(f[maxx]+1)%p;
    			return;
    		}
    		else
    		{
    			if(sum0>=1)
    			{
    				dfs(pos+1,n,sum0-1,sum1,maxx,0,k);
    			}
    			if(sum1>=1)
    			{
    				dfs(pos+1,n,sum0,sum1-1,maxx,(pre!=0)*pre+1,k);
    			}
    		}
    	}
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,m,i;
    	cin>>n>>m;
    	jc[0]=jc_inv[0]=1;
    	for(i=1;i<=n;i++)
    	{
    		inv[i]=qpow(i,p-2,p);
    		jc[i]=jc[i-1]*i%p;
    		jc_inv[i]=jc_inv[i-1]*inv[i]%p;
    	}
    	
    	if(n==m)
    	{
    		for(i=1;i<=n-1;i++)
    		{
    			cout<<0<<" ";
    		}
    		cout<<1<<endl;
    	}
    	else
    	{
    		dfs(1,n,n-m,m,0,0,m/2);
    		for(i=1;i<=m/2;i++)
    		{
    			cout<<f[i]<<" ";
    		}
    		for(i=m/2+1;i<=m;i++)
    		{
    			cout<<(2*C(n-i-1,m-i,p)%p+C(n-i-2,m-i,p)*(n-i-1)%p)%p<<" ";
    		}
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 正解

    • 发现统计 恰好为 \(k\) 的方案数不太好做,考虑统计 至多为 \(k\) 的方案数,然后临项相减即可得到最终结果。统计 至少为 \(k\) 的方案数同理。
    • 观察到 \(n-m\)\(0\) 会将 \(1\) 分割成 \(n-m+1\) 段(每段可以为空),等价于查询 \(\sum\limits_{i=1}^{n-m+1}x_{i}=m(x_{i} \le k)\) 的非负整数解的个数。
    • 考虑组合意义,将 \(m\) 个小球放到 \(n-m+1\) 的盒子里,每个盒子限重为 \(k\)
    • 接着进行二项式反演,设 \(f_{i}\) 表示恰好 \(i\) 个盒子超限的方案数, \(g_{i}\) 表示钦定/至少 \(i\) 个盒子超限的方案数。考虑计算 \(g_{i}\) 的组合意义,先选出 \(i\) 个盒子里各放 \(k+1\) 个小球使其超限,接着将剩下的 \(m-i(k+1)\) 个小球放到 \(n-m+1\) 个盒子里进行插板,有 \(g_{i}=\dbinom{n-m+1}{i}\dbinom{m-i(k+1)+n-m+1-1}{n-m+1-1}=\dbinom{n-m+1}{i}\dbinom{m-i(k+1)+n-m}{n-m}\)
    • 最后有 \(f_{0}=\sum\limits_{i=0}^{n-m+1}(-1)^{i-0}\dbinom{i}{0}g_{i}=\sum\limits_{i=0}^{n-m+1}(-1)^{i}g_{i}\)
    • 不难发现 \(i \le \min(n-m+1,\frac{m}{k+1})\) ,所以时间复杂度为调和级数的 \(O(n \log n)\)
    点击查看代码
    const ll p=1000000007;
    ll inv[400010],jc[400010],jc_inv[400010],sum[400010];
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		a=a*a%p;
    		b>>=1;
    	}
    	return ans;
    }
    ll C(ll n,ll m,ll p)
    {
    	return (n>=m&&n>=0&&m>=0)?(jc[n]*jc_inv[n-m]%p)*jc_inv[m]%p:0;
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,m,i,k;
    	cin>>n>>m;
    	jc[0]=jc_inv[0]=1;
    	for(i=1;i<=n+m;i++)
    	{
    		inv[i]=qpow(i,p-2,p);
    		jc_inv[i]=jc_inv[i-1]*inv[i]%p;
    		jc[i]=jc[i-1]*i%p;
    	}
    	for(k=1;k<=m;k++)
    	{
    		for(i=0;i<=min(n-m+1,m/(k+1));i++)
    		{
    			if(i%2==0)
    			{
    				sum[k]=(sum[k]+C(n-m+1,i,p)*C(m-i*(k+1)+n-m,n-m,p)%p)%p;
    			}
    			else
    			{
    				sum[k]=(sum[k]-C(n-m+1,i,p)*C(m-i*(k+1)+n-m,n-m,p)%p+p)%p;
    			}
    		}
    	}
    	for(i=m;i>=1;i--)
    	{
    		sum[i]=(sum[i]-sum[i-1]+p)%p;
    	}
    	for(i=1;i<=m;i++)
    	{
    		cout<<sum[i]<<" ";
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

\(T3\) P296. 星空遗迹 \(20pts\)

  • 弱化版: QOJ 8046. Rock-Paper-Scissors Pyramid | Gym104065M Rock-Paper-Scissors Pyramid

  • 部分分

    • \(20 \%\) :模拟,时间复杂度为 \(O(qn^{2})\)

      点击查看代码
      char s[200010],tmp[200010];
      char w(char x,char y)
      {
      	if(x==y){return x;}
      	if(x!='R'&&y!='R'){return 'S';}
      	if(x!='S'&&y!='S'){return 'P';}
      	if(x!='P'&&y!='P'){return 'R';}
      	return 'A';
      }
      void f(char s[],int len)
      {
      	for(int i=1;i<=len-1;i++)
      	{
      		s[i]=w(s[i],s[i+1]);
      	}
      }
      char ask(int l,int r)
      {
      	for(int i=l,j=1;i<=r;i++,j++)
      	{
      		tmp[j]=s[i];
      	}
      	for(int i=l,j=r-l+1;i<=r;i++,j--)
      	{
      		f(tmp,j);
      	}
      	return tmp[1];
      }
      int main()
      {
      	freopen("a.in","r",stdin);
      	freopen("a.out","w",stdout);
      	int n,q,pd,l,r,i;
      	char c;
      	cin>>n>>q>>(s+1);
      	for(i=1;i<=q;i++)
      	{
      		cin>>pd;
      		if(pd==1)
      		{
      			cin>>l>>c;
      			s[l]=c;
      		}
      		else
      		{
      			cin>>l>>r;
      			cout<<ask(l,r)<<endl;
      		}
      	}
      	fclose(stdin);
      	fclose(stdout);
      	return 0;
      }
      
    • 另外 \(40 \%\)

      • 先是一些大力结论。

        • 连续的相同元素的个数没有什么用,只保留一个元素参与运算。
        • 如果一段连续的相同元素的左/右边存在能赢它们的字符,可直接删除这整段连续的相同元素。
      • 考虑在从 \(l\) 扫到 \(r\) 的过程中维护一个栈不断插入字符,使得从栈底到栈顶每个元素都能赢在它上面的一个元素,最终的栈底元素即为答案所求,单次询问的时间复杂度为 \(O(n)\)

        • 本质上是构造连续的形如 RPSRPS... 的字符串,或许用胜负关系表示括号序更好理解。
        点击查看代码
        deque<char>q;
        char s[200010];
        char w(char x,char y)
        {
        	if(x==y){return x;}
        	if(x!='R'&&y!='R'){return 'S';}
        	if(x!='S'&&y!='S'){return 'P';}
        	if(x!='P'&&y!='P'){return 'R';}
        	return 'A';
        }
        int main()
        {
        	freopen("a.in","r",stdin);
        	freopen("a.out","w",stdout);
        	int n,m,pd,l,r,i,j;
        	char c;
        	cin>>n>>m>>(s+1);
        	for(j=1;j<=m;j++)
        	{
        		cin>>pd;
        		if(pd==1)
        		{
        			cin>>l>>c;
        			s[l]=c;
        		}
        		else
        		{
        			cin>>l>>r;
        			q.clear();
        			for(i=l;i<=r;i++)
        			{
        				while(q.empty()==0&&w(q.back(),s[i])==s[i])
        				{
        					q.pop_back();
        				}
        				q.push_back(s[i]);
        			}
        			cout<<q.front()<<endl;
        		}
        	}
        	fclose(stdin);
        	fclose(stdout);
        	return 0;
        }
        
  • 正解

    • 考虑数据结构优化上面的内容。
    • 定义定义域为 \(\{ R,P,S \}\) 下的 \(a>b\) 表示 \(a\) 能赢 \(b\)\(a=b\) 表示 \(a,b\) 平局, \(a<b\) 表示 \(b\) 能赢 \(a\)
    • \(f_{i}\) 表示从 \(1\) 开始,在插入 \(i\) 后的栈的大小,有 \(f_{i}=\begin{cases}f_{i-1}+1 & s_{i-1}>s_{i} \\ f_{i} & s_{i-1}=s_{i} \\ \max(f_{i}-1,1) & s_{i-1}<s_{i} \end{cases}\) ,边界为 \(f_{1}=1\)
    • 可以证明,对于全局查询,答案显然来自最后一个 \(f_{i}=1\) 的位置。
    • 考虑去掉转移过程中的和 \(1\)\(\max\) ,则 \([l,r]\) 中最后一个最小的 \(f_{i}\) 即为所求(尽管加上和 \(1\)\(\max\) 后可能也不等于 \(1\) ,但代码写出来是对的,有严格证明了跟我说)。
      • 是否是最后一个最小的 \(f_{i}\) 并不重要,因为其 \(s_{i}\) 都是一样的,中途进行了相互抵消,感性理解吧。
    • \(\{ s \}\) 的单点修改可以转化为对胜负关系前缀和后(即维护栈后)的后缀修改和区间查询最小值。
    点击查看代码
    int f[200010],g[200010];
    char s[200010];
    int w(char x,char y)
    {
    	if(x==y){return 0;}
    	if(x!='R'&&y!='R'){return ('S'==x)?1:-1;}
    	if(x!='S'&&y!='S'){return ('P'==x)?1:-1;}
    	if(x!='P'&&y!='P'){return ('R'==x)?1:-1;}
    	return 2;
    }
    struct SMT
    {
    	struct SegmentTree
    	{
    		int l,r,minn,pos,lazy;
    	}tree[800010];
    	int lson(int x)
    	{
    		return x*2;
    	}
    	int rson(int x)
    	{
    		return x*2+1;
    	}
    	void pushup(int rt)
    	{
    		if(tree[lson(rt)].minn>=tree[rson(rt)].minn)
    		{
    			tree[rt].minn=tree[rson(rt)].minn;
    			tree[rt].pos=tree[rson(rt)].pos;
    		}
    		else
    		{
    			tree[rt].minn=tree[lson(rt)].minn;
    			tree[rt].pos=tree[lson(rt)].pos;
    		}
    	}
    	void build(int rt,int l,int r)
    	{
    		tree[rt].l=l;
    		tree[rt].r=r;
    		if(l==r)
    		{
    			tree[rt].minn=f[l];
    			tree[rt].pos=l;
    			return;
    		}
    		int mid=(l+r)/2;
    		build(lson(rt),l,mid);
    		build(rson(rt),mid+1,r);
    		pushup(rt);
    	}
    	void pushdown(int rt)
    	{
    		if(tree[rt].lazy!=0)
    		{
    			tree[lson(rt)].lazy+=tree[rt].lazy;
    			tree[rson(rt)].lazy+=tree[rt].lazy;
    			tree[lson(rt)].minn+=tree[rt].lazy;
    			tree[rson(rt)].minn+=tree[rt].lazy;
    			tree[rt].lazy=0;
    		}
    	}
    	void update(int rt,int x,int y,int val)
    	{
    		if(x<=tree[rt].l&&tree[rt].r<=y)
    		{
    			tree[rt].lazy+=val;
    			tree[rt].minn+=val;
    			return;
    		}
    		pushdown(rt);
    		int mid=(tree[rt].l+tree[rt].r)/2;
    		if(x<=mid)
    		{
    			update(lson(rt),x,y,val);
    		}
    		if(y>mid)
    		{
    			update(rson(rt),x,y,val);
    		}
    		pushup(rt);
    	}
    	pair<int,int> query(int rt,int x,int y)
    	{
    		if(x<=tree[rt].l&&tree[rt].r<=y)
    		{
    			return make_pair(tree[rt].minn,tree[rt].pos);
    		}
    		pushdown(rt);
    		int mid=(tree[rt].l+tree[rt].r)/2;
    		pair<int,int>p,q;
    		if(y<=mid)
    		{
    			return query(lson(rt),x,y);
    		}
    		else
    		{
    			if(x>mid)
    			{
    				return query(rson(rt),x,y);
    			}
    			else
    			{
    				p=query(lson(rt),x,y);
    				q=query(rson(rt),x,y);
    				return (p.first>=q.first)?q:p;
    			}
    		}
    	}
    }T;
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	int n,m,pd,l,r,i;
    	char c;
    	cin>>n>>m>>(s+1);
    	f[1]=1;
    	for(i=2;i<=n;i++)
    	{
    		g[i]=w(s[i-1],s[i]);
    		f[i]=f[i-1]+g[i];
    	}
    	T.build(1,1,n);
    	for(i=1;i<=m;i++)
    	{
    		cin>>pd;
    		if(pd==1)
    		{
    			cin>>l>>c;
    			if(l-1>=1)
    			{
    				T.update(1,l,n,-g[l]);
    				s[l]=c;		
    				g[l]=w(s[l-1],s[l]);
    				T.update(1,l,n,g[l]);
    			}
    			else
    			{
    				s[l]=c;		
    			}
    			if(l+1<=n)
    			{
    				T.update(1,l+1,n,-g[l+1]);
    				g[l+1]=w(s[l],s[l+1]);
    				T.update(1,l+1,n,g[l+1]);
    			}
    		}
    		else
    		{
    			cin>>l>>r;
    			cout<<s[T.query(1,l,r).second]<<endl;
    		}
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

\(T4\) P297. 纽带 \(10pts\)

  • 弱化版: CF1874F Jellyfish and OEIS
    • 原题多了个条件 \(2\) 的限制。
  • 部分分
    • \(10 \%\) :模拟。时间复杂度为 \(O(n! \times n^{3})\)

      点击查看代码
      const int mod=1000000007;
      int m[50],p[50],cnt[50],f[3000];
      bool cmp(int l,int r)
      {
      	memset(cnt,0,sizeof(cnt));
      	for(int i=l;i<=r;i++)
      	{
      		cnt[p[i]]++;
      	}
      	for(int i=l;i<=r;i++)
      	{
      		if(cnt[i]==0)
      		{
      			return false;
      		}
      	}
      	return true;
      }
      int main()
      {
      	freopen("a.in","r",stdin);
      	freopen("a.out","w",stdout);
      	int n,sum,flag,l,r,i;
      	cin>>n;
      	for(i=1;i<=n;i++)
      	{
      		cin>>m[i];
      		p[i]=i;
      	}
      	do
      	{
      		sum=0;
      		flag=1;
      		for(l=1;l<=n;l++)
      		{
      			for(r=l;r<=m[l];r++)
      			{
      				flag&=(cmp(l,r)==false);
      				if(flag==0)
      				{
      					break;
      				}
      			}
      			if(flag==0)
      			{
      				break;
      			}
      		}
      		if(flag==1)
      		{
      			for(l=1;l<=n;l++)
      			{
      				for(r=l;r<=n;r++)
      				{
      					sum+=(cmp(l,r)==true);
      				}
      			}
      			f[sum]=(f[sum]+1)%mod;
      		}
      	}while(next_permutation(p+1,p+1+n));
      	for(i=1;i<=n*(n+1)/2;i++)
      	{
      		cout<<f[i]<<" ";
      	}
      	fclose(stdin);
      	fclose(stdout);
      	return 0;
      }
      
    • \(20 \%\) :模拟,不难发现若 \([p_{l},p_{l+1}, \dots ,p_{r}]\) 是 $[l,l+1, \dots ,r] $ 的一个排列,则有 \(\begin{cases} \max\limits_{i=l}^{r}\{ p_{i} \}=r \\ \min\limits_{i=l}^{r}\{ p_{i} \}=l \end{cases}\)。时间复杂度为 \(O(n! \times n^{2})\)

      点击查看代码
      const int mod=1000000007;
      int m[50],p[50],f[3000];
      int main()
      {
      	freopen("a.in","r",stdin);
      	freopen("a.out","w",stdout);
      	int n,sum,flag,maxx,minn,l,r,i;
      	cin>>n;
      	for(i=1;i<=n;i++)
      	{
      		cin>>m[i];
      		p[i]=i;
      	}
      	do
      	{
      		sum=0;
      		flag=1;
      		for(l=1;l<=n;l++)
      		{
      			maxx=0;
      			minn=0x7f7f7f7f;
      			for(r=l;r<=m[l];r++)
      			{
      				maxx=max(maxx,p[r]);
      				minn=min(minn,p[r]);
      				flag&=(maxx!=r||minn!=l);
      				if(flag==0)
      				{
      					break;
      				}
      			}
      			if(flag==0)
      			{
      				break;
      			}
      		}
      		if(flag==1)
      		{
      			for(l=1;l<=n;l++)
      			{
      				maxx=0;
      				minn=0x7f7f7f7f;
      				for(r=l;r<=n;r++)
      				{
      					maxx=max(maxx,p[r]);
      					minn=min(minn,p[r]);
      					sum+=(maxx==r&&minn==l);
      				}
      			}
      			f[sum]=(f[sum]+1)%mod;
      		}
      	}while(next_permutation(p+1,p+1+n));
      	for(i=1;i<=n*(n+1)/2;i++)
      	{
      		cout<<f[i]<<" ";
      	}
      	fclose(stdin);
      	fclose(stdout);
      	return 0;
      }
      
  • 正解
    • 析合树上跑 \(DP\) ,直接挂官方题解了。

总结

  • \(T2\) 数组开小挂了 \(5pts\)
  • \(T4\) 没有意识到自己判断是否是排列和枚举右端点可以继承,所以写的是 \(O(n! \times n^{3})\) ,挂了 \(15pts\)

后记

  • \(T1\) 的数据范围出锅了,话说 \(miaomiao\) 还会自己造数据?

  • \(T4\) 富有启发性意义的题目背景。

posted @ 2024-10-04 15:11  hzoi_Shadow  阅读(68)  评论(0编辑  收藏  举报
扩大
缩小