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;
}

浙公网安备 33010602011771号