第 45 屆國際大學生程序設計競賽(ICPC)亞洲區域賽(濟南)


A Matrix Equation +++

B Number Game ???

C Stone Game ---

D Fight against involution ---

E Tree Transform ???

F Gcd Product ???

G Xor Transformation ---

H Path Killer ???

I Random Walk On Tree ---

J Tree Constructer !!!

構造題 難想啊
因為樹是天然的二分圖
我們先黑白染色 個數少的為基准(原因后面講)
然后排列成二分圖的形式
以左側為基准(假設左側個數少)
首先左側的點自己不能連邊 所以低兩位為10
右側同理 但是右側得和左側連邊 所以右側低兩位是01
左側的點初始值設為 2^60-1-1
右側的點初始值設為 1
然后依次考慮左側的點 從第3位(由低到高)開始 去掉這一位
在與他相鄰的點中加上這一位 這樣就構成了鎖和鑰匙的形式

#include<bits/stdc++.h>
using namespace std;
const int N = 105;
vector<int>to[N];
typedef long long ll;
const ll inf = (1ll<<60)-1ll;
ll val[N];
#define pb push_back
vector<int>f[2];
void dfs(int u,int fa,int d){
	f[d].pb(u);
	for(auto v:to[u]){
		if(v==fa) continue;
		dfs(v,u,d^1);
	}
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i = 1; i < n; i++){
		int x,y;
		scanf("%d%d",&x,&y);
		to[x].pb(y);
		to[y].pb(x);
	}
	dfs(1,0,0);
	if((int)f[0].size()>(int)f[1].size())
		swap(f[0],f[1]);
	
	for(auto v:f[0]){
		val[v]=inf-1ll;		
	}
	
	for(auto v:f[1]){
		val[v]=1;
	}
	ll now=2ll;
	for(auto v:f[0]){
		val[v]^=(1ll<<now);
		for(auto k:to[v]){
			val[k]|=(1ll<<now);
		}
		now++;
	}
	for(int i = 1; i <= n; i++) printf("%lld%c",val[i],i==n?'\n':' ');
	return 0;
}

K Kth Query ???

L Bit Sequence !!!

一道數位dp,首先m的大小並不是很大,所以數位dp到最后一位的值可以直接遍歷m,現在就是要存哪些狀態了,100是小於2的七次方也就是128的,所以加上一個小於m的值最多會影響第八位小后的那些連續的1,我們把這些連續的1的奇偶存起來,如果是奇數的話加上那個小於m的值進位后還是奇數,不影響,但是偶數的話會變成奇數,改變了奇偶性,還有就是后七位要存起來,第八位以后的一的個數也要存起來,具體看代碼
pos是位置,h是后七位的值,g是第八位之后的連續1的個數,c是第八位之后的1的奇偶性,flag是限制

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
ll dp[70][128][2][2][2];
ll w[150],a[150];
int m;
ll x;
ll get(int h,int g,int c){
	int ans=1;
	if(g==1)g=0;
	else g=1;
	for(int i=0;i<m;i++){
		if(i+h>=128){
			if((__builtin_parity((i+h)%128)^c^g)!=a[i])ans=0;
		}
		else{
			if((__builtin_parity((i+h)%128)^c)!=a[i])ans=0;
		}
	}
	return ans;
}
ll dfs(int pos,int h,int g,int c,int flag){
	if(pos==0){
		return get(h,g,c);
	}
	if(dp[pos][h][g][c][flag]!=-1)return dp[pos][h][g][c][flag];
	int maxn=1;
	if(flag==1)maxn=w[pos];
	ll ans=0;
	for(int i=0;i<=maxn;i++){
		if(pos>=8){
			if(i==1){
				ans=ans+dfs(pos-1,h,g^1,c^i,flag&(i==maxn));
			}
			else{
				ans=ans+dfs(pos-1,h,0,c^i,flag&(i==maxn));
			}
		}
		else{
			ans=ans+dfs(pos-1,2*h+i,g,c,flag&(i==maxn));
		}
	}
	dp[pos][h][g][c][flag]=ans;
	return ans;
}
ll solve(){
	int cnt=0;
	while(x!=0){
		w[++cnt]=x%2;
		x=x/2;
	}
	return dfs(cnt,0,0,0,1);
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		memset(dp,-1,sizeof(dp));
		scanf("%d %lld",&m,&x);
		for(int i=0;i<m;i++){
			scanf("%d",&a[i]);
		}
		printf("%lld\n",solve());
	}
}

M Cook Pancakes! ---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM