2025“钉耙编程”中国大学生算法设计暑期联赛(2)
数上的图
#include<iostream>
using namespace std;
#define ll long long
ll n,x,y;
ll cnt(ll x){
ll res=0;
while(x){
if(x&1)res++;
x>>=1;
}
return res;
}
ll lowbit(ll x){return x&(-x);}
int main(){
std::ios::sync_with_stdio(false);
int T;cin>>T;
while(T--){
cin>>n>>x>>y;
if(x==y)cout<<0<<'\n';
else if(cnt(x)==cnt(y))cout<<1<<'\n';
else if(lowbit(x)==lowbit(y))cout<<1<<'\n';
else {
cout<<2<<'\n';
}
}
}
并
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
cin>>T;
while (T--){
long long n;
cin>>n;
double ans = 3.0 * n / 2.0;
printf("%.4lf\n", ans);
}
return 0;
}
半
#include<iostream>
using namespace std;
#include<map>
#define endl '\n'
const int N=2000010;
int n;int a[N];int b[N];int ans[N];
int mp[N];
int nmp[N];
int tr[N];
int lowbit(int x){return x&(-x);}
int query(int x){
int res=0;
for(int i=x;i>0;i-=lowbit(i)){
res+=tr[i];
}return res;
}
void add(int x,int k){
for(int i=x;i<=n;i+=lowbit(i))tr[i]+=k;
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T;cin>>T;
while(T--){
cin>>n;for(int i=1;i<=n;i++)tr[i]=0;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
for(int i=1;i<=n;i++){
mp[a[i]]=i;ans[a[i]]=i-1;
nmp[i]=a[i];
}
for(int i=1;i<=n;i++)b[i]=mp[b[i]];
// cout<<"b";for(int i=1;i<=n;i++)cout<<b[i]<<" ";cout<<endl;
for(int i=1;i<=n;i++){
//cout<<nmp[b[i]]<<" ";
ans[nmp[b[i]]]+=i-1-query(b[i]);
add(b[i],1);
}//cout<<endl;
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}cout<<'\n';
}
}
苹果树
可以稍微积累一下,是中心修改
只对父亲和重儿子修改,给该节点加一个tag
查询时,如果查到轻儿子(当且仅当链首),本应该被修改但没有修改,那一定是以它的父亲为中心修改时,没有修改它,那我们就把之前给他父亲的tag加上。
如果查到重儿子,已经被更新
查到根节点,也是特殊的链首,它只能被其儿子修改,fa是0,tag是0,也满足轻儿子这个情况
#include<iostream>
using namespace std;
#include<vector>
const int N=100010;
int a[N];int n,m,rt,mod;
vector<int> G[N];
int fa[N];int dep[N];int siz[N];int son[N];
int top[N];int id[N];int nw[N];int cnt_id=0;int tag[N];
void dfs1(int u,int f){
fa[u]=f;dep[u]=dep[f]+1;siz[u]=1;
for(auto v:G[u]){
if(v==f)continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v])son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp;id[u]=++cnt_id;nw[cnt_id]=a[u];
if(!son[u])return ;
dfs2(son[u],tp);
for(auto v:G[u]){
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
struct Tree{
int l,r;
int mx;
}tr[4*N];
void pushup(Tree& u,Tree& l,Tree& r){
u.l=l.l;u.r=r.r;
u.mx=max(l.mx,r.mx);
}void pushup(int u){pushup(tr[u],tr[u<<1],tr[u<<1|1]);}
void bui(int u,int l,int r){
tr[u]={l,r,nw[l]};
if(l==r)return ;
int mid=(l+r)>>1;
bui(u*2,l,mid);
bui(u*2+1,mid+1,r);
pushup(u);
}
void modify(int u,int x,int y,int k){
if(x<=tr[u].l&&tr[u].r<=y){
tr[u].mx+=k;
return ;
}
int mid=(tr[u].l+tr[u].r)>>1;
if(x<=mid)modify(u*2,x,y,k);
if(y>=mid+1)modify(u*2+1,x,y,k);
pushup(u);
}
Tree query(int u,int x,int y){
if(x<=tr[u].l&&tr[u].r<=y)return tr[u];
int mid=(tr[u].l+tr[u].r)>>1;
if(y<=mid)return query(u*2,x,y);
else if(x>=mid+1)return query(u*2+1,x,y);
else {
Tree res;
Tree leftt=query(u*2,x,y);
Tree rightt=query(u*2+1,x,y);
pushup(res,leftt,rightt);
return res;
}
}
int query_path(int u,int v){
int res=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res=max(res,query(1,id[top[u]],id[u]).mx);
res=max(res,nw[id[top[u]]]+tag[id[fa[top[u]]]]);//上面的查询中有链首
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
res=max(res,query(1,id[v],id[u]).mx);
if(v==top[v])res=max(res,nw[id[v]]+tag[id[fa[v]]]);//u和v在同一条链上了,v深度小,如果有链首,就是v
// 如果v==top[v],上面的查询中就有链首
return res;
}
int main(){
std::ios::sync_with_stdio(false);
int T;cin>>T;
while(T--){
cin>>n>>m;cnt_id=0;
for(int i=1;i<=n;i++){son[i]=0;G[i].clear();tag[i]=0;}
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n-1;i++){
int u,v;cin>>u>>v;G[u].push_back(v);G[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
bui(1,1,n);
while(m--){
int op;
cin>>op;
if(op==1){
int x,y;cin>>x>>y;
cout<<query_path(x,y)<<'\n';
}else {
int x,z;cin>>x>>z;
if(fa[x]){modify(1,id[fa[x]],id[fa[x]],z);nw[id[fa[x]]]+=z;}//修改父亲
if(son[x]){modify(1,id[son[x]],id[son[x]],z);nw[id[son[x]]]+=z;}//修改轻儿子
tag[id[x]]+=z;//给x加tag
}
}
}
}
子集
既然不相邻,那隔一个和隔两个都可以加入计算,爆搜1221537个状态,O(1e6*63)为什么可以接受?
空间只能说特别小??
太水了,只dfs(1)也过了
#include<iostream>
using namespace std;
#define int long long
/*
void dabiao(int step){
int g[100]={0};
g[0]=0;g[1]=1;g[2]=1;
for(int i=3;i<=50;i++){
g[i]=g[i-3]+g[i-2];
}
cout<<g[50]+g[49]<<endl;
}
*/
int n;
int a[51];
int tem[64];int ans=0;
int insert(int x) {
int res=-1;
for (int i = 63; ~i; --i) {
if (!(x >> i))
continue;
if (!tem[i]) {
tem[i] = x;res=i;
break;
}
x ^= tem[i];
}
return res;
}
void dfs(int step){
if(step>=n+1){
int res=0;
for(int i=63;i>=0;i--)res=max(res,res^tem[i]);
ans=max(ans,res);
return ;
}
int t=insert(a[step]);
dfs(step+2);
dfs(step+3);
if(t!=-1)tem[t]=0;
}
signed main(){
std::ios::sync_with_stdio(false);
int T;cin>>T;
while(T--){
cin>>n;ans=0;
for(int i=1;i<=n;i++)
cin>>a[i];
dfs(1);
dfs(2);
cout<<ans<<'\n';
}
}

浙公网安备 33010602011771号