Codeforces Round #652 (Div. 2)

D. TediousLee

我們先處理一下葉子結點(ye)和1個兒子的結點(one)之間的關係 

顯然  

ye[i]=one[i-1]*2+ye[i-1]    one[i]=ye[i-1]

找規律題  觀察3號樹 4號樹和6號樹的關係  發現4號樹的葉子 在6號樹變成了“爪子” 每個爪子貢獻爲4  然後我們去掉4號樹的葉子 發現剛好得到了一棵完整的3號樹

於是   猜想規律是  f[n]=f[n-3]+ye[i-2]*4 然後用樣例驗證一下就知道了

#include<bits/stdc++.h>
using namespace std;
const int N = 2e6+20;
typedef long long ll;
const ll mod = 1e9+7;
ll ye[N],one[N],f[N];
int main(){
	int t;
	scanf("%d",&t);
	ye[1]=1,one[1]=0;
	for(int i = 2; i <= 2e6; i++){
		ye[i]=(one[i-1]*2ll%mod+ye[i-1])%mod;
		one[i]=ye[i-1];
	}
	f[1]=f[2]=0;
	f[3]=4;
	for(int i = 4; i <= 2e6; i++)
	f[i]=(f[i-3]+ye[i-2]*4ll%mod)%mod;
	while(t--){
		int n;
		scanf("%d",&n);
		printf("%lld\n",f[n]);
	}
	return 0;
}

E. DeadLee

設 d[i]爲喜歡第i個食物的人數   w[i]和題目的意思一樣 如果d[i]>w[i] 我們尚且不能確定是不是可以   但是如果d[i]<=w[i]  那麼這些人無論什麼時候喫 都是可以的(不會出現食物不足的情況) 鑑於次進行貪心  對於d[i]<=w[i] 的食物 我們加入隊列 並且把喫這些食物的人放在最後面(因爲他們一定能喫到  就讓不一定能喫到的先喫)  然後對於這些人喫的另外的一種食物x 讓它的d[x]--  也就是說喜歡喫這個食物的人減少一個 因爲我們已經安排他喫i食物了  如果d[x]==w[x] 那麼把x食物加入隊列 在繼續進行下去  

如果隊列爲空 但是我們還沒有遍歷n個食物的話 說明不能滿足要求 輸出“dead”

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
#define pa pair<int,int>
vector<pa>v[N];
int d[N],w[N],ans[N],vis[N];
queue<int>Q;
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i++) scanf("%d",&w[i]);
	for(int i = 1; i <= m; i++){
		int x,y;
		scanf("%d%d",&x,&y);
		v[x].push_back(make_pair(y,i));
		v[y].push_back(make_pair(x,i));
		d[x]++;d[y]++; 
	} 
	for(int i = 1; i <= n; i++)
	if(d[i]<=w[i]) Q.push(i);
	int tot=m;
	for(int i = 1; i <= n; i++){
		if(Q.empty()) return puts("DEAD"),0;
		int g = Q.front();Q.pop();
		for(auto j:v[g]){
			if(vis[j.second]) continue;
			vis[j.second]=1;
			ans[tot--]=j.second;
			d[j.first]--;
			if(d[j.first]==w[j.first]) Q.push(j.first);
		}
	}
	puts("ALIVE");
	for(int i = 1; i <= m; i++) printf("%d ",ans[i]);
	puts("");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章