D. Reset K Edges
显然对于每个k每个答案具有单调性
我们考虑二分一个能保留的最大长度 x
然后我们自上至下 肯定不好操作 我们考虑自下而上
对于每次到达了我们最大长度x 我们再断开是最优的
可以感性理解一下
因为我们越往上走 包括的节点就越多 而对于每个节点 被直接接到根节点肯定是更好的
最后我们要让这个点的高度变成0(对父节点是根节点的点 就不用了 反正都连在一起了)
这样return的时候 下一个节点才是高度1
时间复杂度是O(nlogn)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 1e9+7;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
vector<int>g[N];
int n,k,h[N],ok;
void dfs(int u,int depth,int fa){
h[u]=1;
for(auto v:g[u]){
dfs(v,depth,u);
h[u]=max(h[u],h[v]+1);
}
if(h[u]==depth&&fa!=1){
k--;
if(k<0)ok = false;
h[u]=0;
}
}
void solve() {
cin>>n>>k;
for(int i=1;i<=n;i++)g[i].clear(),h[i]=0;
for(int i=2;i<=n;i++){
int u;cin>>u;
g[u].push_back(i);
}
int l=1,r=n;
while(l<r){
int mid=l+r>>1;
int cnt=k;
ok=true;
dfs(1,mid,1);
if(ok)r=mid;
else l=mid+1;
k=cnt;
}
cout<<l<<endl;
}
signed main(){
fast
int T;cin>>T;
while(T--) {
solve();
}
return ~~(0^_^0);
}
C. Card Game
//只有我觉得C比D难嘛
我们观察样例 显然发现平局好像只有一种
我们构造平局 发现Alex必须拿到的牌必须是0110 0110 01....
我们假设Alex拿到的牌组是x 就是这个平局
因为每个牌的等级都不同(这样就可以看成是一个?进制
所以这个串是可直接比较的
我们手玩一下样例 也可以发现 只要小于x 并且 01数量相同 那就算一种方案
我们数位dp即可
最后别忘了减法的时候mod要加一个mod 不然就会和我一样罚时爆炸
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int f[1010][1010];
void init(){
for(int i=1;i<=1000;i++){
for(int j=0;j<=i;j++){
if(j==0||i==j)f[i][j]=1;
else (f[i][j]=f[i-1][j-1]+f[i-1][j])%=mod;
}
}
}
int dp(int x){
vector<int>nums;
int last=0,res=0;
while(x){if(x%2==1)last++;nums.push_back(x%2),x/=2;}
for(int i=(int)nums.size()-1;i>=0;i--){
int r=nums[i];
if(r){
(res+=f[i][last])%=mod;
last--;
}
}
return res;
}
void solve() {
int n;cin>>n;
int now=0;
for(int i=0;i<n;i++){
now<<=1;
if(i%4+1==2||i%4+1==3){
now+=1;
}
}
int t=dp(now);
cout<<(f[n][n/2]-t-1+mod)%mod<<' '<<t%mod<<' '<<1<<endl;
}
signed main(){
fast
int T;cin>>T;
while(T--) {
init();
solve();
}
return ~~(0^_^0);
}
标签:Educational,const,int,Codeforces,--,136,mod,节点,define
From: https://www.cnblogs.com/ycllz/p/16744037.html