2024“钉耙编程”中国大学生算法设计超级联赛(4)
比赛
2024/7/29
加载过慢请开启缓存 浏览器默认开启
迟来的第一周总结…
第一周一共四场比赛:总的来说还有很多东西没学,或者学的不深,个人感觉八月之前应该在不停的学新东西了,八月之后得对算法加深一些理解和掌握。比赛得时候,签到和能出得思维大家都一样,后期就看谁知识点学过或者掌握的更深了…
vector<PII>e[N];
int n,m,c,minn,dist[N];
bool st[N];
void Dijkstra(int u){
minn=1e18;
for(int i=1;i<=n;i++)dist[i]=1e18,st[i]=0;
priority_queue<PII,vector<PII>,greater<PII> >q;
dist[u]=0;
q.push({dist[u],u});
while(q.size()){
auto [dis,ver]=q.top();
q.pop();
if(st[ver])continue;
st[ver]=1;
for(auto [v,w]:e[ver]){
if(v==u)minn=min(minn,dis+w);
if(st[v])continue;
if(dist[v]>dis+w){
dist[v]=dis+w;
q.push({dist[v],v});
}
}
}
}
void solve(){
cin>>n>>m>>c;
int ans=0;
for(int i=1;i<=m;i++){
int u,v,z;cin>>u>>v>>z;
e[u].pb({v,z});
if(z<=c)ans=1;
}
for(int i=1;i<=n;i++){
Dijkstra(i);
if(minn<=c){ans=2;break;}
}
cout<<ans<<"\n";
}
题面:
分析:
对于区间位运算容易想到拆位,对x进行从高位到低位拆位分析:
1.当位为0时如果数组所有元素的第i位一共有奇数个1,那么无论怎么分配,总有一个段内有奇数个1,异或后结果为1,显然导致整体大于x。
2.当i位为0时如果有偶数个1,此时只能就近两两一组去保证异或为0还有组数最多,同时。
3.当i位为1时如果有奇数个1,此时不做任何处理,只能一段一个1.
4.当i位为1时如果有偶数个1,那么两两一组既能保证异或为0,还能保证组数最多,并且此时分组个数可以直接作为答案的一种取max,当然如果每个单独一组不做处理那么数组间异或结果为1,虽然此时不能当作答案,但是之后的数组的分配可能有更多的答案个数,所以也要把不做处理的情况传递下取去。
因为在第4个情况的时候,我们总是不做处理传递下去,并没有真正的处理x当前位相等的情况。所以我们对x进行+1,那么即使传递下去相等情况,那么也可以取答案。
代码: