A - 牛能和宝石

签到题

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[N],b[N];
int n;
int main()
{IO;int T=1;//cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++) cin>>b[i];sort(a+1,a+1+n);sort(b+1,b+1+n);int res=0;for(int i=1;i<=n;i++) res=max(res,a[i]+b[n-i+1]);cout<<res<<'\n';}return 0;}

B - 牛妹和01串

签到题

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[N],b[N];
int n;
int main()
{IO;int T=1;//cin>>T;while(T--){string s;cin>>s;int res=0,cnt0=0,cnt1=0;for(auto t:s){if(t=='1') cnt1++;if(t=='0') cnt0++;if(cnt0&&cnt1){res++;cnt0=0;cnt1=0;}}cout<<res<<'\n';}return 0;
}

C - 矩阵消除游戏

m,nm,nm,n很小考虑直接枚举
行列都枚举会TLE,考虑优化:如果行确定那么选择列可以贪心。

TLE代码——枚举行列
//lajiTLE代码
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=20;
int a[N][N];
int n,m,k;
vector<int> state[N];
int lowbit(int x)
{return x&-x;
}
int calc(int x)
{int res=0;while(x){x-=lowbit(x);res++;}return res;
}
ll solve(int r,int c)
{ll res=0;for(int i=0;i<n;i++)for(int j=0;j<m;j++)if((r>>i&1)||(c>>j&1)) res+=a[i][j];return res;
}
int main()
{IO;int T=1;//cin>>T;while(T--){cin>>n>>m>>k;for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j];k=min(k,min(n,m));for(int i=0;i<1<<min(n,m);i++) state[calc(i)].push_back(i);ll res=0;for(int r=0;r<=k;r++){int c=k-r;for(int i=0;i<state[r].size();i++){int nowr=state[r][i];for(int j=0;j<state[c].size();j++){int nowc=state[c][j];res=max(res,solve(nowr,nowc));}}}cout<<res<<'\n';}return 0;}
AC代码——枚举行贪心列
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=20;
int a[N][N];
int n,m,k;
vector<int> state[N];
int lowbit(int x)
{return x&-x;
}
int calc(int x)
{int res=0;while(x){x-=lowbit(x);res++;}return res;
}
int b[N];
ll solve(int row,int cnt)
{ll res=0;for(int j=0;j<m;j++){b[j]=0;for(int i=0;i<n;i++){if(row>>i&1) continue;b[j]+=a[i][j];}}sort(b,b+m);reverse(b,b+m);for(int i=0;i<n;i++)if(row>>i&1)for(int j=0;j<m;j++) res+=a[i][j];for(int i=0;i<cnt;i++)res+=b[i];return res;
}
int main()
{IO;int T=1;//cin>>T;while(T--){cin>>n>>m>>k;for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j];k=min(k,min(n,m));for(int i=0;i<1<<min(n,m);i++) state[calc(i)].push_back(i);ll res=0;for(int r=0;r<=k;r++){int c=k-r;for(int i=0;i<state[r].size();i++){int nowr=state[r][i];res=max(res,solve(nowr,c));}}cout<<res<<'\n';}return 0;}

D - 迷宫

题解好像是dp做的,我dijkstra瞎搞出来了。
分析题目不难知道向上走和向左走没什么用,于是只考虑向右走和向下走

向右走的代价为0(不需要堵路)。
如果能向右走,那么如果在该点向下走那么就要花费1代价(堵路),否则向下走的代价为0。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1010;
int g[N][N];
int n,m;
int dist[N][N];
bool st[N][N];
char s[N][N];
struct node
{int d,x,y;bool operator<(const node& o) const{return d>o.d;}
};
void bfs()
{memset(dist,0x3f,sizeof dist);memset(st,0,sizeof st);dist[1][1]=0;priority_queue<node> q;q.push({0,1,1});while(q.size()){int x=q.top().x,y=q.top().y;q.pop();if(st[x][y]) continue;st[x][y]=1;int a,b;int ok1=1,ok2=0;a=x,b=y+1;if(a<1||b<1||a>n||b>m||g[a][b]) ok1=0;else {if(dist[a][b]>dist[x][y]){dist[a][b]=dist[x][y];q.push({dist[a][b],a,b});}}a=x+1,b=y;if(a<1||b<1||a>n||b>m||g[a][b]) ok2=0;else {if(dist[a][b]>dist[x][y]+ok1){dist[a][b]=dist[x][y]+ok1;q.push({dist[a][b],a,b});}}}
}
int main()
{IO;int T=1;//cin>>T;while(T--){cin>>n>>m;for(int i=1;i<=n;i++) cin>>s[i]+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)g[i][j]=s[i][j]-'0';bfs();if(dist[n][m]==0x3f3f3f3f) cout<<-1<<'\n';else cout<<dist[n][m]<<'\n';}return 0;}

E - 最大GCD

首先暴力把每个aia_iai​的约数搞出来,用一个vector存储一下,d[i]d[i]d[i]表示存在约数是iii的aia_iai​所在的位置下标。询问同样先把所有约数搞出来,然后逆序去vector<int> d[]二分查找看看是否在所给区间内即可。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int n,m;
vector<int> d[N];
int main()
{//IO;int T=1;//cin>>T;while(T--){cin>>n>>m;for(int i=1;i<=n;i++){int a;cin>>a;for(int j=1;j<=a/j;j++){if(a%j) continue;d[j].push_back(i);if(j!=a/j) d[a/j].push_back(i);}}while(m--){int l,r,x;cin>>l>>r>>x;vector<int> dx;for(int i=1;i<=x/i;i++){if(x%i) continue;dx.push_back(i);if(i!=x/i) dx.push_back(x/i);}sort(dx.begin(),dx.end());reverse(dx.begin(),dx.end());for(auto t:dx){if(!d[t].size()) continue;int lnow=lower_bound(d[t].begin(),d[t].end(),l)-d[t].begin();if(lnow>=d[t].size()) continue;if(d[t][lnow]<=r) {cout<<t<<'\n';break;}}}}return 0;}

F - XOR TREE

分析一下不难发现每个点对答案的贡献有以下规律:

  • 如果路径点数是奇数个点,那么等效于所有偶数次序的点被记录一次
  • 如果路径点数是偶数个点,那么所有点都被计入一次

①路径点数可以根据求树上路径距离间接求得
②对于一条路径上的奇偶点,可以根据端点的奇偶性+深度的奇偶性来确定。

因此树剖后根据dfs序建立两棵线段树分别维护深度是奇数和深度是偶数点的区间异或值。
查询和修改的时候只需要分类讨论以下即可。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
//***************************************************************
int read()
{int x=0;char c=getchar();while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();return x;
}
//***************************************************************
int n,q;
int w[N],a[N],b[N];
int h[N],e[2*N],ne[2*N],idx;
void add(int a,int b)
{e[idx]=b;ne[idx]=h[a];h[a]=idx++;
}
int fa[N],dep[N],sz[N],son[N];
void dfs1(int u,int p)
{sz[u]=1;    fa[u]=p,dep[u]=dep[p]+1;for(int i=h[u];i!=-1;i=ne[i]){int j=e[i];if(j==p) continue;dfs1(j,u);sz[u]+=sz[j];if(sz[j]>sz[son[u]])son[u]=j;}
}
int timestamp,dfn[N],top[N];
void dfs2(int u,int t)
{dfn[u]=++timestamp;top[u]=t;if(!son[u]) return;dfs2(son[u],t);for(int i=h[u];i!=-1;i=ne[i]){int j=e[i];if(j==fa[u]||j==son[u]) continue;dfs2(j,j);}
}
int lca(int u,int v)
{while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);u=fa[top[u]];}return dep[u]<dep[v]?u:v;
}
int dist(int u,int v)
{return dep[u]+dep[v]-2*dep[lca(u,v)];
}
struct node1
{struct node2{int l,r;int val;}tree[N<<2];void pushup(int u){tree[u].val=tree[u<<1].val^tree[u<<1|1].val;}void build(int u,int l,int r,int w[]){tree[u]={l,r};if(l==r) {tree[u].val=w[l];return;}int mid=l+r>>1;build(u<<1,l,mid,w),build(u<<1|1,mid+1,r,w);pushup(u);}void modify(int u,int pos,int val){if(tree[u].l==tree[u].r){tree[u].val=val;return;}int mid=tree[u].l+tree[u].r>>1;if(pos<=mid) modify(u<<1,pos,val);else modify(u<<1|1,pos,val);pushup(u);}int query(int u,int l,int r){if(tree[u].l>=l&&tree[u].r<=r) return tree[u].val;int v=0;int mid=tree[u].l+tree[u].r>>1;if(l<=mid) v^=query(u<<1,l,r);if(r>mid) v^=query(u<<1|1,l,r);return v;}int cquery(int u,int v){int val=0;while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);val^=query(1,dfn[top[u]],dfn[u]);u=fa[top[u]];}if(dep[u]>dep[v]) swap(u,v);val^=query(1,dfn[u],dfn[v]);return val;}
}A,B;
int main()
{//IO;int T=1;//cin>>T;while(T--){n=read(),q=read();memset(h,-1,sizeof h);for(int i=1;i<=n;i++) w[i]=read();for(int i=1;i<n;i++){int u,v;u=read(),v=read();add(u,v),add(v,u);}dfs1(1,0);dfs2(1,1);for(int i=1;i<=n;i++){if(dep[i]&1) a[dfn[i]]=w[i];else b[dfn[i]]=w[i];}A.build(1,1,n,a);B.build(1,1,n,b);while(q--){int op,x,y;op=read(),x=read(),y=read();if(op==1){if(dep[x]&1) A.modify(1,dfn[x],y);else B.modify(1,dfn[x],y);}else{int d=dist(x,y);int res=0;if(d&1){res=A.cquery(x,y)^B.cquery(x,y);}else{if(dep[x]&1) res=B.cquery(x,y);else res=A.cquery(x,y);}cout<<res<<'\n';}}}return 0;}

要加油哦~

牛客练习赛 58——树链剖分相关推荐

  1. 牛客练习赛58 C.矩阵消除游戏

    牛客练习赛58 C.矩阵消除游戏 题目链接 题目描述 牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是n行m列,第i行第j列的单元格的权值为ai,ja_{i,j}ai,j​ ,牛妹可以进行k个回合的游戏, ...

  2. 矩阵消除游戏--牛客练习赛58

    题意: 牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是n行m列,第i行第j列的单元格的权值为ai,j,a_{i,j},ai,j​,,牛妹可以进行k个回合的游戏,在每个回合,牛妹可以选择一行或者选择一列, ...

  3. 牛客练习赛26 E-树上路径 (树链剖分+线段树)

    链接:https://ac.nowcoder.com/acm/contest/180/E 来源:牛客网 树上路径 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语 ...

  4. 牛客多校7 - A National Pandemic(树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一棵树,再给出 m 次操作,每次操作分为三种类型,dist( x , y ) 代表点 x 和点 y 之间的距离: 1 pos val:将点 pos 位置的值增加 va ...

  5. 牛客练习赛34 - C little w and Segment Coverage(思维、树状数组)

    title: 牛客练习赛34 - C little w and Segment Coverage(思维.树状数组) date: 2018-12-15 16:36:55 tags: [树状数组,思维] ...

  6. 计蒜客 - Distance on the tree(树链剖分+离线处理+线段树)

    题目链接:点击查看 题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数 题目分析:因为一开始不会主席 ...

  7. 牛客练习赛73 D 离别(线段树+右端点排序离线查询)

    牛客练习赛73 D 离别 思路: 对于每一个固定的右端点i,我们都找到一个区间(l,r)使得区间中的点为左端点时 里面最大的的种数为k. 这个可以用队列或者vector来维护. 然后我们对于q个查询, ...

  8. BZOJ1576: [Usaco2009 Jan]安全路经Travel(树链剖分)

    Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...

  9. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

最新文章

  1. tns(thrift 分布式组件)介绍
  2. NetBeans 时事通讯(刊号 # 146 - May 13, 2011)
  3. python3 gzip 压缩/解压
  4. python读取文件第n行-python读取文件第n行
  5. 整理find命令输出格式
  6. 设计模式学习 - 工厂模式
  7. 华为鸿蒙系统初探之HUAWEI DevEco Studio Hello World
  8. jar逆向工具Luyten
  9. 量化交易策略代码java_3.量化交易策略基本框架
  10. python launcher卸载不了_python2的卸载
  11. root后充电很慢,root后开机慢
  12. 《机器学习实战》(八)-- 树回归
  13. 微信小程序代码保存后,自动格式化代码
  14. 【巴什博弈】HDOJ2188悼念512汶川大地震遇难同胞——选拔志愿者
  15. 计算机网络【1】 TCP/IP
  16. html设计动画小黄人,用纯css3画一个小黄人并实现动画效果
  17. 如何在UnrealEngine虚幻引擎中加载Web页面
  18. 升压芯片很简单(三),SX1308升压芯片大串讲
  19. Excel快捷键速查
  20. SAP 采购发票校验之 红字发票 MIRO <转载>

热门文章

  1. python调用robotframework_robotframework+python接口自动化的点滴记录(2)
  2. python开发一个自己的技术网站_手把手教你写网站:Python WEB开发技术实战
  3. android交叉编译libxml2,Openwrt 交叉编译libxml2(示例代码)
  4. [JavaWeb-HTML]HTML标签_语义化标签
  5. C++继承的继承方式
  6. I - Interesting Permutation Gym - 102394I(排列组合)
  7. c语言开发环境 推荐,C语言复习和VC++6.0开发环境推荐.ppt
  8. Java将五个整数存入整形数组_异常处理:从命令行输入5个整数,放入一整型数组,然后打印输出。。。...
  9. C. Orac and LCM(数论lcm, gcd)
  10. Trie:hdu 4825、1251、1247、Poj 3764