The 9th Hebei Collegiate Programming Contest(A,D,F,H~K,M)

A.棋盘

思路:模拟,队友写的

#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
using namespace std;
const int N=3e5;
ll a[N];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        vector<ll>a(n+5),b(n+5);
        for(ll i=1;i<=n;i++)cin>>a[i];
        for(ll i=1;i<=n;i++)cin>>b[i];
        ll flag=0;
        if(n==1){
            if(a[1]>b[1])flag=3;
            else if(a[1]<b[1])flag=1;
            else flag=2;
        }
        else if(n==2){
            if(a[1]+a[2]>b[1]+b[2]||a[1]+b[1]>a[2]+b[2]) flag=3;
            else if(a[1]+a[2]<b[1]+b[2]&&a[1]+b[1]<a[2]+b[2]) flag=1;
            else flag=2;
        }
        else{
                vector<ll>pre(n+4,0),sub(n+4,0);
                //ll sum1=0,sum2=0;
                ll sum=0;
                ll flag1=0;
                for(ll i=1;i<=n;i++){
                    pre[i]=pre[i-1]+a[i];
                    sub[i]=sub[i-1]+b[i];
                    sum+=(a[i]+b[i]);
                }
                //绝对赢
                ll k=(n-1)/2;
                if(pre[k]+sub[k]>sum-pre[k]-sub[k]){
                    cout << "Mandy" << endl;
                    continue;
                }
                if(sum-pre[n-k]-sub[n-k]>pre[n-k]+sub[n-k]){
                    cout << "brz" << endl;
                    continue;
                }

                //a可以平
                if(pre[k]+sub[k]==sum-pre[k]-sub[k]){
                    flag=max(flag,2ll);
                }
                //b可以平
                if(sum-pre[n-k]-sub[n-k]==pre[n-k]+sub[n-k]){
                    flag1=1;
                }

                //n为偶数,回头
                if(n%2==0){
                    if(pre[n/2]+sub[n/2]>sum-pre[n/2]-sub[n/2]){
                        flag=max(flag,3ll);
                    }
                    else if(pre[n/2]+sub[n/2]==sum-pre[n/2]-sub[n/2]){
                        flag=max(flag,2ll);
                    }
					else flag=max(flag,1ll);
                }
                
                //A走第一行
                if(pre[n]>sub[n]){
                    flag=max(flag,3ll);
                }
                else if(pre[n]==sub[n]){
                    flag=max(flag,2ll);
                }
                else{
                    flag=max(flag,1ll);
                }

                if(flag1){
                    flag=min(flag,2ll);
                }
        }
        if(flag==3){
            cout << "Mandy" << endl;
        }
        else if(flag==2){
            cout << "draw" << endl;
        }
        else{
            cout << "brz" << endl;
        }
    }
}

D.金麦园

思路:二分极限范围,然后再统计即可,注意二分里面用队列或者双指针维护,不能nlognlogn

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
#define ll long long 

const int INF=0x3f3f3f3f;
const int N=2468;
const ll mod=1e9+7;


void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
signed main()
{
	fio();
	ll t=1;
	while(t--)
	{
		ll n,k;
		cin>>n>>k;
		vector<ll>a(n+5),pre(n+5,0);
		for(ll i=1;i<=n;i++)cin>>a[i];
		sort(a.begin()+1,a.begin()+1+n);
		for(ll i=1;i<=n;i++){
			pre[i]=pre[i-1]+a[i];
		}
		ll l=1,r=a[n]-a[1];
		function<ll(ll)>ck=[&](ll x){
			ll cnt=0;
			queue<ll>f;
			for(ll i=1;i<=n;i++){
				if(f.empty()){
					f.push(a[i]);
				}
				else {
					while(!f.empty()&&f.front()<a[i]-x){
						cnt+=f.size()-1;
						f.pop();
					}
					f.push(a[i]);
				}
			}
			while(!f.empty()){
				cnt+=f.size()-1;
				f.pop();
			}
			if(cnt>=k)return 1ll;
			else return 0ll;
		};
		while(l<r){
			ll mid=l+r>>1;
			if(ck(mid))r=mid;
			else l=mid+1; 
		}
		ll cnt=0;
		ll ans=0;
		for(ll i=1;i<=n;i++){
			ll d=a[i]+r-1;
			ll j=upper_bound(a.begin()+1+i,a.begin()+1+n,d)-a.begin();
			j--;
			if(j<=i)continue;
			else {
				cnt+=j-i;
				ans+=(pre[j]-pre[i])-a[i]*(j-i);
			}
		}
		ans+=(k-cnt)*r;
		cout<<ans<<endl;
	}
	return 0;
}

F.不死国的生命树

思路:类似倍增lca,直接套用倍增形式即可,然后用正常深度维护倍增点

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
#define ll int 

const int INF=0x3f3f3f3f;
const int N=2468;
const ll mod=1e9+7;


void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll fa[2500000][36];
ll dep[2500000];
signed main()
{
    fio();
    ll t=1;
    while(t--)
    {
        ll n;
        cin>>n;
        vector<ll>a(n+5);
        for(ll i=1;i<=n;i++){
            cin>>a[i];
        }
        vector<ll>g[n+5];
        for(ll i=2;i<=n;i++){
            ll x;
            cin>>x;
            g[x].push_back(i);
        }
        vector<ll>vis(n+4,0);
        function<void(ll,ll)>dfs=[&](ll x,ll z){
            ll f=vis[a[x]+1];
            fa[x][0]=f;
            dep[x]=dep[z]+1;
            ll d=vis[a[x]];
            vis[a[x]]=x;
            for(ll i=1;i<=32;i++){
                fa[x][i]=fa[fa[x][i-1]][i-1];
            }
            for(auto j:g[x]){
                dfs(j,x);
            }
            vis[a[x]]=d;
        };
        dfs(1,0);
        function<ll(ll,ll)>lca=[&](ll x,ll sd){
            ll u=a[x];
            for(ll i=32;i>=0;i--){
                if(dep[fa[x][i]]>=sd)x=fa[x][i];
            }
            return abs(u-a[x])+1;
        };
        ll q;cin>>q;
        while(q--){
            ll l,r;
            cin>>l>>r;
            r=dep[r];
            cout<<lca(l,r)<<endl;
        }
    }
    return 0;
}

H.What is all you need?

思路:签到,无需多言

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
string f;
cin>>f;
ll j=f.size()-1-11;
string k=f.substr(j,12);
if(k=="isallyouneed"){
    cout<<"Yes"<<endl;
    cout<<f.substr(0,f.size()-12)<<endl;
}
else cout<<"No"<<endl;
}

I.感染

思路:换根dp,每次换根,可以认为变短的少扩散了一轮,变长的多扩了一轮

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
#define ll long long 

const int INF=0x3f3f3f3f;
const int N=2468;
const ll mod=1e9+7;


void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
signed main()
{
    fio();
    ll t=1;
	cin>>t;
    while(t--)
    {
        ll n;
		cin>>n;
		vector<ll>g[n+5];
		for(ll i=1;i<n;i++){
			ll l,r;
			cin>>l>>r;
			g[l].push_back(r);
			g[r].push_back(l);
		}
		vector<ll>dep(n+4,0),sd(n+4,0),sz(n+4,0);
		function<void(ll,ll,ll)>dfs=[&](ll x,ll f,ll cs){
			// sd[x]=cs;
			sz[x]=1;
			// dep[x]=dep[f]+1;
			for(auto j:g[x]){
				if(f==j)continue;
				// sda[x]=max(sd[x],dfs(j,x,cs+1));
				// sz[x]+=sz[j];
				dfs(j,x,cs+1);
				sz[x]+=sz[j];
			}
			// return sd[x];
		};
		dfs(1,0,0);
		ll maxn=-1e18;
		vector<ll>ans;
		function<void(ll,ll,ll)>ck=[&](ll x,ll f,ll v){
			if(maxn<v){
				ans.clear();
				maxn=v;
				ans.push_back(x);
			}
			else if(maxn==v)ans.push_back(x);
			for(auto j:g[x]){
				if(j==f)continue;
				sz[x]-=sz[j];
				ll u=sz[j];
				sz[j]+=sz[x];
				ck(j,x,v+u-sz[x]);
				sz[j]-=sz[x];
				sz[x]+=sz[j];
			}
		};
		ck(1,0,0);
		cout<<ans.size()<<endl;
		sort(ans.begin(),ans.end());
		for(auto j:ans)cout<<j<<" ";
		cout<<endl;
    }
    return 0;
}

J.Generate 01 String

思路:用栈简单维护即可

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
#define ll long long 

const int INF=0x3f3f3f3f;
const int N=2468;
const ll mod=1e9+7;


void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

ll ksm(ll a,ll b){
	ll res=1;
	while(b){
		if(b&1){
			res*=a;
			res%=mod;
		}
		a*=a;
		a%=mod;
		b>>=1;
	}
	return res%mod;
}

pair<ll,ll>k[N][N][2];//n条线段对于m个点的斜率
vector<int> posi[N];//n个线段对于点的排序
pair<ll,ll>seg[N];
pair<ll,ll> poi[N];
int now;
int jd(pair<ll,ll>&a1,pair<ll,ll>&a2){
	if(a1.first*a2.second<a2.first*a1.second){
		return -1;
	}
	else if(a1.first*a2.second>a2.first*a1.second) {
		return 1;
	}
	return 0;
}
bool cmp(int &a,int &b){
	if(k[now][a][0]!=k[now][b][0]){
	return k[now][a][0].first*k[now][b][0].second<k[now][b][0].first*k[now][a][0].second;
	}
	return k[now][a][1].first*k[now][b][1].second>k[now][b][1].first*k[now][a][1].second;
}
signed main()
{
	fio();
	ll t=1;
	while(t--)
	{
		string s;
		cin>>s;
		stack<char>st;
		int zero=0,one=0;
		for(int i=0;i<s.length();i++){
			zero+=s[i]=='0';
			one+=s[i]=='1';
		}
		if(zero!=one){
			cout<<"-1"<<endl;
		}else{
			cout<<s.length()/2<<endl;
			int now=1;
			for(int i=0;i<s.length();i++){
				if(st.empty()){
					if(s[i]=='0'){
						cout<<now<<" "<<"1"<<endl;
					}else{
						cout<<now<<" 2"<<endl;
					}
					st.push(s[i]);
				}else{
					if(st.top()==s[i]){
						st.push(s[i]);
						if(s[i]=='0'){
							cout<<now<<" "<<"1"<<endl;
						}else{
							cout<<now<<" 2"<<endl;
						}
					}else{
						now++;
						st.pop();
					}
				}
			}
		}
	}
	return 0;
}

K.UNO!

思路:用数组模拟链表维护,队友写的

#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
using namespace std;
const int N=3e5;
int pre[N][2];//0往前1往后
ll a[N];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        pre[i][0]=(i-1+n)%n;
        pre[i][1]=(i+1)%n;
    }
    // for(int i=0;i<n;i++){cout<<pre[i][0]<<" "<<pre[i][1]<<"\n";}
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    string s;
    cin>>s;
    int jd=1,now=0;
    for(int j=0;j<m;j++){
        if(s[j]=='C'){
            a[now]--;
            if(a[now]==0){
                int nxt=pre[now][1];
                int prr=pre[now][0];
                pre[nxt][0]=prr;
                pre[prr][1]=nxt;
            }
        }else if(s[j]=='S'){
            a[now]--;
            if(a[now]==0){
                int nxt=pre[now][1];
                int prr=pre[now][0];
                pre[nxt][0]=prr;
                pre[prr][1]=nxt;
            }
            now=pre[now][jd];//禁止
            now+=n;
            now%=n;
        }else if(s[j]=='R'){
            a[now]--;
            if(a[now]==0){
                int nxt=pre[now][1];
                int prr=pre[now][0];
                pre[nxt][0]=prr;
                pre[prr][1]=nxt;
            }
            jd=1-jd;
        }else{//'D'
            a[now]--;
            if(a[now]==0){
                int nxt=pre[now][1];
                int prr=pre[now][0];
                pre[nxt][0]=prr;
                pre[prr][1]=nxt;
            }
            now=pre[now][jd];//禁止
            now+=n;
            now%=n;
            a[now]+=2;
        }
        now=pre[now][jd];
        now+=n;
        now%=n;
    }
    for(int i=0;i<n;i++){
        cout<<a[i]<<"\n";
    }
}

M.第九届河北省大学生程序设计竞赛

思路:二进制枚举

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
#define ll long long 

const int INF=0x3f3f3f3f;
const int N=2468;
const ll mod=1e9+7;


void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
signed main()
{
	fio();
	ll t=1;
	while(t--)
	{
		ll n,m;
		cin>>n>>m;
		string f[m+5];
		ll flag=0;
		for(ll i=1;i<=m;i++)cin>>f[i],f[i]='0'+f[i];
		vector<bool>vis(n+5,0);
		vector<ll>a(4,0),b(4,0);
		for(ll i=1;i<=3;i++)cin>>a[i];
		for(ll i=1;i<=3;i++)cin>>b[i];
		for(ll i=1;i<=(1ll<<n)-1;i++){
			ll cnt=0;
			for(ll j=0;j<n;j++){
					vis[j+1]=0;
				if((1ll<<j)&i){
					cnt++;
					vis[j+1]=1;
				}
			}
			if(cnt>=10&&cnt<=13){
				vector<ll>cn(m+4,0);
				for(ll j=1;j<=m;j++){
					for(ll d=1;d<=n;d++){
						if(f[j][d]=='1'&&vis[d]==1){
							cn[j]++;
						}
					}
				}
				sort(cn.begin()+1,cn.begin()+1+m);
				if(cn[m-a[1]+1]==b[1]&&cn[m-a[2]+1]==b[2]&&cn[m-a[3]+1]==b[3]){
					flag=cnt;
					break;
				}
			}
		}
		if(flag==0)cout<<-1<<endl;
		else {
			cout<<flag<<endl;
			for(ll j=1;j<=n;j++){
				if(vis[j])cout<<j<<" ";
			}
			cout<<endl;
		}
	}
	return 0;
}
posted @ 2025-05-30 10:16  长皆  阅读(92)  评论(0)    收藏  举报