牛客周赛 Round 89
D
思维题:仔细考虑题目的性质
任意次改变k个灯的状态,由此我们操作两次,两次操作的灯中只有一盏灯不同,所以k-1个灯的状态,2个灯的状态改变.
基于此
- 如果k是奇数,那么我们选择k个灯,改变它们的状态,而刚才我们提到可以改变2个灯的状态,于是不断的改变这k个灯中,任意2个不重复的灯的状态,最终只会使得一盏灯的状态改变.
因此,我们可以改变任意一盏灯的状态,由此可以无限次改变灯的状态,所以灯的所有状态都可以改变
- 如果k是偶数,那么只能改变偶数盏灯的状态,比如改变0,2,4,..,2^x盏灯的状态,所以总的只会改变全部状态的一半即\(2^(n-1)\)种状态
最后特判k==n时只有两种状态
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,k;
const int mod=1e9+7;
ll quick_pow(ll a,ll b){
ll cnt=1;
while(b){
if(b&1){
cnt=cnt*a%mod;
}
a=(a*a)%mod;
b>>=1;
}
return cnt%mod;
}
int main(){
cin>>n>>k;
if(n==k){
cout<<2<<endl;
return 0;
}
if(k&1){
cout<<quick_pow(2,n)%mod;
}
else cout<<quick_pow(2,n-1)<<endl;
return 0;
}
F/G
从下往上看,如果该节点灯亮,为了减少操作次数
- 首先考虑灭了该当前节点的灯,以及父节点(因为这样考虑,可以父节点就不需要再找儿子节点同时关灯
- 其次考虑灭了当前节点的灯,以及子子节点的灯
没有父节点,或者父节点已经关了,才考虑2
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
bool book[maxn];
int n;
vector<pair<int,int> > q;
int cnt=0;
struct node{
int v,next;
}e[maxn<<1];
int head[maxn];
void add(int u,int v){
e[++cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt;
}
void dfs(int u,int f){
int sum=0,pos=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;if(v==f) continue;
dfs(v,u);
if(book[v]==0){//找一个未灭灯的子节点
pos=v;
++sum;
}
}
if(sum && book[u]==0){//当前节点灯未灭,且子节点也有未灭灯的点
if(f==0 || book[f]==1){//选择当前节点及儿子节点灭灯
book[u]=book[pos]=1;
q.push_back({u,pos});
}
else {//父节点和当前节点灭灯
book[f]=book[u]=1;
q.push_back({u,f});
}
}
}
void solve(){
cin>>n;
for(int i=1;i<n;++i){
int u,v;cin>>u>>v;
add(u,v);add(v,u);
}
dfs(1,0);
cout<<q.size()<<"\n";
for(auto [x,y]:q){
cout<<x<<" "<<y<<"\n";
}
return ;
}
int main(){
solve();
return 0;
}

浙公网安备 33010602011771号