cf 2000+练习(2)

C. Another Array Problem

https://codeforces.com/problemset/problem/1763/C
题解:操作一次后[l,r]变为同样的数值,若再进行一次操作,那么就会全变为0!故对于n>=4的情况,我们只需找到最大值所在位置,然其长度>=2的一侧全变为0,然后将其的值赋到一端,然后对于剩下的数进行两次操作全变为0,即可让所有数变为最大值,剩下的只需特判n=2,3即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;

int a[200100];
void solve(){
	int n;cin>>n;
	int res=0;
	for(int i=1;i<=n;i++) cin>>a[i],res=max(res,a[i]);
	if(n==2){
		int ans=max(a[1]+a[2],2*abs(a[2]-a[1]));
		cout<<ans<<endl;
		return;
	}
	else if(n==3){
		int ans=a[1]+a[2]+a[3];
		ans=max(a[1]*3,ans);
		ans=max(a[3]*3,ans);
		ans=max(abs(a[1]-a[2])*3,ans);
		ans=max(abs(a[3]-a[2])*3,ans);
		ans=max(abs(a[1]-a[3])*3,ans);
		cout<<ans<<endl;
		return;
	}
	cout<<res*n<<endl;
}
signed main(){
	int T;cin>>T;
	while(T--) solve();
}

D. GCD Queries 2100

https://codeforces.com/problemset/problem/1762/D
题解:为找到0,我们首先想到两个点一组选取然后筛出0,发现条件比较有限,为了使每次至少筛去一个非0点,我们需要得到更多条件,想到若选取三个点x,y,z 询问u=gcd(x,y) ,v=gcd(y,z),可以通过比较二者的大小产生有用信息:u=v时y!=0,u>v时z!=0,u<v时x!=0,从而可以每次筛去一个点,即可在2n次询问下得到答案。
代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;

queue<int> q;
int ask(int x,int y){
	cout<<"? "<<x<<" "<<y<<endl;
	int ans;cin>>ans;
	return ans;
}
void solve(){
	int n;cin>>n;
	if(n==2){
		cout<<"! "<<1<<" "<<2<<endl;
		int x;cin>>x;
		return;
	}
	for(int i=1;i<=n;i++) q.push(i);
	for(int i=1;i<=n-2;i++){
		int x=q.front();q.pop();
		int y=q.front();q.pop();
		int z=q.front();q.pop();
		int a=ask(x,y),b=ask(y,z);
		int u,v;
		if(a==b) u=x,v=z;
		else if(a>b) u=x,v=y;
		else u=y,v=z;
		q.push(u),q.push(v);
	}
	int x=q.front();q.pop();
	int y=q.front();q.pop();
	cout<<"! "<<x<<" "<<y<<endl;
	int m;cin>>m;
}
signed main(){
	int T;cin>>T;
	while(T--) solve();
}

Priority Queue

https://www.luogu.com.cn/problem/CF1542D
题解:根据数据范围以及问题形式想到计数dp,前i位有j个数比x小作为状态,枚举每一个非-的数值在前i位置有j个数比其小时的出现次数,最后对计数求和即可,转移方程见代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
int a[1010],b[1010],tot,f[550][550];
signed main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		char c;cin>>c;
		if(c=='+'){
			int x;cin>>x;
			b[++tot]=x;
			a[i]=x;
		}
		else{
			a[i]=-1;
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		int x=a[i];
		if(x<0) continue;
		for(int j=0;j<=n;j++)
		for(int k=0;k<=n;k++) 
		f[j][k]=0;
		f[0][0]=1;
		for(int j=1;j<=n;j++){
		if(j==i){
			for(int k=0;k<=n;k++)
			f[j][k]=f[j-1][k];
			continue;
		}
			for(int k=0;k<=n;k++){
				if(a[j]==-1){
					f[j][k]=(f[j-1][k]+f[j-1][k+1])%mod;
					if(k==0&&j<i) f[j][0]=(f[j][0]+f[j-1][0])%mod;
				}
				else if(a[j]<x){
					if(k==0) f[j][k]=f[j-1][k];
					else
					f[j][k]=(f[j-1][k-1]+f[j-1][k])%mod;
				}
				else if(a[j]>x) f[j][k]=2*f[j-1][k]%mod;
				else if(a[j]==x){
					if(j==i) continue;
					if(j<i) {
					if(k==0) f[j][k]=f[j-1][k];
					else
					f[j][k]=(f[j-1][k-1]+f[j-1][k])%mod;
					}
					else f[j][k]=2*f[j-1][k]%mod;
				}
			}
		}
		int res=0;
		for(int j=0;j<=n;j++){
			res=(res+f[n][j])%mod;
		}
		ans=(ans+x*res%mod)%mod;
	}
	cout<<ans;
}
posted @ 2023-03-14 00:24  wrong,anser  阅读(35)  评论(0)    收藏  举报