zoukankan      html  css  js  c++  java
  • Codeforces Round #669 (Div. 2) 题解 (ABC)

    最近有点忙,这场就写到C吧,D我口胡一下(懒得补)

    A. Ahahahahahahahaha

    题目读错了,没看到 (n) 是偶数(藏在这么隐蔽的地方),题目就复杂好多但是居然有解

    先说正解,因为只有偶数,如果1的个数小于等于 (dfrac n 2),就删掉所有的1,否则删掉所有0,并且在1的个数是奇数的时候删掉一个1

    (然后讲一下新题目,不看也罢)n不一定是偶数。找到连续的两个1或者连续的两个0,无视它们就不会对结果产生影响。删掉它们后(并不是真的删掉因为最后还是要输出的),序列只可能是0101..或者1010..(0和1交替出现)。对于0101..,删掉所有的1就行了。对于1010..,我们删掉第一个0和第3个以及之后所有的1,变成11000..,这样删掉的数量不超过n/2。还有一个特殊情况10,要删掉第一个1

    为什么A题能被我想得这么复杂,实属迷惑行为

    //#pragma GCC optimize(3)
    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    #define mst(a,x) memset(a,x,sizeof(a))
    #define fi first
    #define se second
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    typedef long long ll; typedef double lf; typedef pair<ll,ll> pii;
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0); ll read(); lf readf();
    const int inf=~0u>>2; const ll INF=~0ull>>2; const lf pi=acos(-1.0);
    template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
    const int N=200010; const ll mod=(1?1000000007:998244353); ll mul(ll,ll,ll); ll qpow(ll,ll,ll);
    #define int ll
    vector<int> stk;
    int a[N],ans[N];
    void Solve(){
    	int n=read(); stk.clear();
    	repeat(i,0,n){
    		a[i]=read(); stk<<i; //"<<" means push_back
    		if(stk.size()>=2 && a[stk.rbegin()[0]]==a[stk.rbegin()[1]])
    			stk.pop_back(),stk.pop_back();
    	}
    	fill(ans,ans+n,1);
    	if(stk.size()==2)
    		for(auto i:stk)ans[i]=!a[i];
    	else if(stk.size()>=2)ans[stk[1]]=0;
    	repeat(i,3,stk.size())if(a[stk[i]])ans[stk[i]]=0;
    	cout<<accumulate(ans,ans+n,0)<<endl;
    	repeat(i,0,n)if(ans[i])cout<<a[i]<<' ';
    	cout<<endl;
    }
    signed main(){
    	//freopen("data.txt","r",stdin);
    	int T=1; T=read();
    	repeat(ca,1,T+1){
    		Solve();
    	}
    	return 0;
    }
    ll read(){
    	ll x; if(scanf("%lld",&x)==-1)exit(0);
    	return x;
    }
    lf readf(){
    	lf x; if(scanf("%lf",&x)==-1)exit(0);
    	return x;
    }
    ll mul(ll a,ll b,ll m=mod){
    	return a*b%m;
    }
    ll qpow(ll a,ll b,ll m=mod){
    	ll ans=1;
    	for(;b;a=mul(a,a,m),b>>=1)
    		if(b&1)ans=mul(ans,a,m);
    	return ans;
    }
    

    B. Big Vova

    第一个数显然是原序列的最大值。如果处理出了前i个数,我们计算前i个数的gcd为d,找到剩下的数里gcd(d,a[i])最大的a[i]作为第i+1个数即可

    //#pragma GCC optimize(3)
    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    #define mst(a,x) memset(a,x,sizeof(a))
    #define fi first
    #define se second
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    typedef long long ll; typedef double lf; typedef pair<ll,ll> pii;
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0); ll read(); lf readf();
    const int inf=~0u>>2; const ll INF=~0ull>>2; const lf pi=acos(-1.0);
    template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
    const int N=200010; const ll mod=(1?1000000007:998244353); ll mul(ll,ll,ll); ll qpow(ll,ll,ll);
    #define int ll
    vector<int> a,ans;
    void Solve(){
    	int n=read(); a.clear(); ans.clear();
    	repeat(i,0,n)a<<read();
    	int now=*max_element(a.begin(),a.end());
    	repeat(i,0,n){
    		int p=max_element(a.begin(),a.end(),[&](int x,int y){
    			return __gcd(now,x)<__gcd(now,y);
    		})-a.begin();
    		now=__gcd(now,a[p]);
    		ans<<a[p];
    		swap(a[p],a.back());
    		a.pop_back();
    	}
    	for(auto i:ans)cout<<i<<' ';
    	cout<<endl;
    }
    signed main(){
    	//freopen("data.txt","r",stdin);
    	int T=1; T=read();
    	repeat(ca,1,T+1){
    		Solve();
    	}
    	return 0;
    }
    ll read(){
    	ll x; if(scanf("%lld",&x)==-1)exit(0);
    	return x;
    }
    lf readf(){
    	lf x; if(scanf("%lf",&x)==-1)exit(0);
    	return x;
    }
    ll mul(ll a,ll b,ll m=mod){
    	return a*b%m;
    }
    ll qpow(ll a,ll b,ll m=mod){
    	ll ans=1;
    	for(;b;a=mul(a,a,m),b>>=1)
    		if(b&1)ans=mul(ans,a,m);
    	return ans;
    }
    

    C. Chocolate Bunny

    因为模的运算很头疼,但是一个非常有用的性质直接能秒掉这题。如果有两个数a,b(a≠b),如果a%b>b%a,那么a的值就是a%b,否则b的值是b%a

    上述操作可以消耗两次询问直接确定一个数的值。我们每次拿出两个未知的位置进行两次询问,也就是说每次都有一个未知的数变成已知的数。只要2(n-1)次询问后即可确定n-1个数,最后那个数就不用说了

    //#pragma GCC optimize(3)
    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    #define mst(a,x) memset(a,x,sizeof(a))
    #define fi first
    #define se second
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    typedef long long ll; typedef double lf; typedef pair<ll,ll> pii;
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0); ll read(); lf readf();
    const int inf=~0u>>2; const ll INF=~0ull>>2; const lf pi=acos(-1.0);
    template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
    const int N=200010; const ll mod=(1?1000000007:998244353); ll mul(ll,ll,ll); ll qpow(ll,ll,ll);
    #define int ll
    int ans[N];
    int query(int x,int y){
    	cout<<"? "<<x<<' '<<y<<endl; cout.flush();
    	int a; cin>>a;
    	cout<<"? "<<y<<' '<<x<<endl; cout.flush();
    	int b; cin>>b;
    	if(a>b){ans[x]=a; return y;}
    	else {ans[y]=b; return x;}
    } 
    void Solve(){
    	int n; cin>>n;
    	int p=1;
    	repeat(i,2,n+1)
    		p=query(p,i);
    	cout<<"! ";
    	repeat(i,1,n+1){
    		if(ans[i]==0)ans[i]=n;
    		cout<<ans[i]<<' ';
    	}
    	cout<<endl;
    }
    signed main(){
    	//freopen("data.txt","r",stdin);
    	int T=1; //T=read();
    	repeat(ca,1,T+1){
    		Solve();
    	}
    	return 0;
    }
    ll read(){
    	ll x; if(scanf("%lld",&x)==-1)exit(0);
    	return x;
    }
    lf readf(){
    	lf x; if(scanf("%lf",&x)==-1)exit(0);
    	return x;
    }
    ll mul(ll a,ll b,ll m=mod){
    	return a*b%m;
    }
    ll qpow(ll a,ll b,ll m=mod){
    	ll ans=1;
    	for(;b;a=mul(a,a,m),b>>=1)
    		if(b&1)ans=mul(ans,a,m);
    	return ans;
    }
    

    D题,这个性质很容易(并不)想到单调栈。单调栈弹出的数和当前正在访问的数就刚好可以构成题目中的规则2或者规则3(取决于单增的单调栈还是单减的单调栈)

  • 相关阅读:
    CodeForces 894C Marco and GCD Sequence|构造
    【学习笔记】KMP中的border及其应用
    NOIP2020游记
    CodeForces 1006F Xor-Paths|Meet in the middle
    Luogu P4809 [CCC 2018]最大战略储备|最小生成树
    Luogu P5304 [GXOI/GZOI2019]旅行者|最短路
    Luogu P4552 [Poetize6] IncDec Sequence|差分
    Luogu P6852 Mex|构造
    Codeforces 1292C Xenon's Attack on the Gangs|DP,贪心
    [LeetCode]7. Reverse Integer
  • 原文地址:https://www.cnblogs.com/axiomofchoice/p/13638435.html
Copyright © 2011-2022 走看看