D. TediousLee
我們先處理一下葉子結點(ye)和1個兒子的結點(one)之間的關係
顯然
找規律題 觀察3號樹 4號樹和6號樹的關係 發現4號樹的葉子 在6號樹變成了“爪子” 每個爪子貢獻爲4 然後我們去掉4號樹的葉子 發現剛好得到了一棵完整的3號樹
於是 猜想規律是 然後用樣例驗證一下就知道了
#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;
}