I. Max answer

链接:https://nanti.jisuanke.com/t/38228

思路:

枚举最小值,单调栈确定最小值的边界,用线段树+前缀和维护最小值的左右区间

实现代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 const ll M = 5e5+;
const ll inf = 1e9;
ll a[M],Li[M],Ri[M],sum[M];
ll lmn[M<<],lmx[M<<],rmn[M<<],rmx[M<<],pre[M],nex[M];
void build(ll l,ll r,ll rt){
if(l == r){
lmn[rt] = nex[l];
lmx[rt] = nex[l];
rmn[rt] = pre[l];
rmx[rt] = pre[l];
return ;
}
ll m = (l + r) >> ;
build(lson); build(rson);
lmn[rt] = min(lmn[rt<<],lmn[rt<<|]);
rmn[rt] = min(rmn[rt<<],rmn[rt<<|]);
lmx[rt] = max(lmx[rt<<],lmx[rt<<|]);
rmx[rt] = max(rmx[rt<<],rmx[rt<<|]);
} ll getlmn(ll L,ll R,ll l,ll r,ll rt){
if(L <= l&&R >= r){
return lmn[rt];
}
ll m = (l + r) >> ;
ll ret = inf;
if(L <= m) ret = min(ret,getlmn(L,R,lson));
if(R > m) ret = min(ret,getlmn(L,R,rson));
return ret;
} ll getrmn(ll L,ll R,ll l,ll r,ll rt){
if(L <= l&&R >= r){
return rmn[rt];
}
ll m = (l + r) >> ;
ll ret = inf;
if(L <= m) ret = min(ret,getrmn(L,R,lson));
if(R > m) ret = min(ret,getrmn(L,R,rson));
return ret;
} ll getlmx(ll L,ll R,ll l,ll r,ll rt){
if(L <= l&&R >= r){
return lmx[rt];
}
ll m = (l + r) >> ;
ll ret = ;
if(L <= m) ret = max(ret,getlmx(L,R,lson));
if(R > m) ret = max(ret,getlmx(L,R,rson));
return ret;
} ll getrmx(ll L,ll R,ll l,ll r,ll rt){
if(L <= l&&R >= r){
return rmx[rt];
}
ll m = (l + r) >> ;
ll ret = ;
if(L <= m) ret = max(ret,getrmx(L,R,lson));
if(R > m) ret = max(ret,getrmx(L,R,rson));
return ret;
} int main()
{
ll n;
scanf("%lld",&n);ll ans = ,flag = ,mid = n+;
for(ll i = ;i <= n;i ++){
scanf("%lld",&a[i]);
if(a[i]>&&flag==) mid = i,flag = ;
ans += a[i]; pre[i] = ans;
}
ans = ;
for(ll i = n;i >= ;i --){
ans += a[i]; nex[i] = ans;
}
build(,n,);
stack<ll>s;
for(ll i = ;i <= n;i ++){
while(s.size()&&a[s.top()]>=a[i]) s.pop();
if(s.empty()) Li[i] = ;
else Li[i] = s.top()+;
s.push(i);
}
while(!s.empty()) s.pop();
for(ll i = n;i >= ;i --){
while(s.size()&&a[s.top()]>=a[i]) s.pop();
if(s.empty()) Ri[i] = n;
else Ri[i] = s.top()-;
s.push(i);
}
while(!s.empty()) s.pop();
ll cnt = ,num,mx=;
for(ll i = ;i <= n;i ++){
if(a[i] >= ){
cnt = a[i];
cnt += getlmx(Li[i],i,,n,)-nex[i];
cnt += getrmx(i,Ri[i],,n,)-pre[i];
mx = max(mx,cnt*a[i]);
//cout<<cnt<<" "<<getlmx(Li[i],i,1,n,1)<<" "<<getrmx(i,Ri[i],1,n,1)<<endl;
}
else{
cnt = a[i];
cnt += getlmn(Li[i],i,,n,)-nex[i];
cnt += getrmn(i,Ri[i],,n,)-pre[i];
mx = max(mx,cnt*a[i]);
//cout<<cnt<<" "<<getlmn(Li[i],i,1,n,1)-nex[i]<<" "<<getrmn(i,Ri[i],1,n,1)-pre[i]<<endl;
}
//cout<<a[i]<<" "<<Li[i]<<" "<<Ri[i]<<" "<<mx<<endl;
}
printf("%lld\n",mx);
}

J. Distance on the tree

链接:https://nanti.jisuanke.com/t/38229

思路;

序列上求任意区间有多少个数小于k

https://www.cnblogs.com/kls123/p/9568553.html

就是这道题扔到树上,一开始想复杂了,还以为是点对的数量。

从根节点向下遍历每次遍历到一条边看作是一次修改,下标为val的点+1

但是这种方法建的主席树是类似权值线段树的,下标和树是没关系的,有关系的是这是第几次修改的,所以在树上应该用root跳

注意 在树上跳的时候表示当前点前后的点时应该用fa[],son[],而不是+1,-1.

实现代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 3e5+;
int ls[M*],rs[M*],sum[M*],a[M],b[M],root[M];
int cnt1,cnt,head[M],dep[M],siz[M],fa[M],son[M],wt[M],top[M],tid[M],rk[M];
int idx,tot;
struct node{
int w,to,next;
}e[M*]; void add(int u,int v,int c){
e[++cnt1].to=v;e[cnt1].next=head[u];e[cnt1].w=c;head[u]=cnt1;
e[++cnt1].to=u;e[cnt1].next=head[v];e[cnt1].w=c;head[v]=cnt1;
}
void dfs1(int u,int faz,int deep){
dep[u] = deep;
siz[u] = ;
fa[u] = faz;
for(int i = head[u];i ;i=e[i].next){
int v = e[i].to;
if(v != fa[u]){
wt[v] = e[i].w;
dfs1(v,u,deep+);
siz[u] += siz[v];
if(son[u]==-||siz[v]>siz[son[u]])
son[u] = v;
}
}
} void dfs2(int u,int t){
top[u] = t;
tid[u] = tot;
rk[tot] = wt[u];
//cout<<1<<endl;
tot++;
if(son[u] == -) return ;
dfs2(son[u],t);
for(int i = head[u];i;i=e[i].next){
int v = e[i].to;
if(v != son[u]&&v != fa[u])
dfs2(v,v);
}
} void update(int old,int &k,int l,int r,int p){
k = ++idx;
ls[k] = ls[old]; rs[k] = rs[old];
sum[k] = sum[old] + ;
if(l == r) return ;
int mid = (l + r) >> ;
if(p <= mid) update(ls[old],ls[k],l,mid,p);
else update(rs[old],rs[k],mid+,r,p);
} int query(int old,int k,int L,int R,int l,int r){
if(L <= l&&R >= r) return sum[k] - sum[old];
int mid = (l + r) >> ;
int ret = ;
if(L <= mid) ret += query(ls[old],ls[k],L,R,l,mid);
if(R > mid) ret += query(rs[old],rs[k],L,R,mid+,r);
return ret;
} int ask(int x,int y,int l,int r){
int ans = ;
int fx = top[x],fy = top[y];
while(fx != fy){
if(dep[fx] < dep[fy]) swap(fx,fy),swap(x,y);
if(fx == ) ans += query(root[tid[fx]],root[tid[x]],l,r,,cnt);
else ans += query(root[tid[fa[fx]]],root[tid[x]],l,r,,cnt);
x = fa[fx]; fx = top[x];
}
if(x==y) return ans;
if(dep[x] > dep[y]) swap(x,y);
ans += query(root[tid[x]],root[tid[y]],l,r,,cnt);
return ans;
} void dfs(int u,int fa){
update(root[tid[fa]],root[tid[u]],,cnt,wt[u]);
for(int i = head[u];i;i=e[i].next){
int v = e[i].to;
if(v == fa) continue;
dfs(v,u);
}
} int l[M],r[M],x[M],u[M],v[M],w[M];
int Find(int x){
int num = lower_bound(b+,b++cnt,x)-b;
return num;
} int main()
{
int m,n;
scanf("%d%d",&n,&m); tot = ;
memset(son,-,sizeof(son));
for(int i = ;i < n;i ++){
scanf("%d%d%d",&u[i],&v[i],&w[i]);
b[i] = w[i];
}
for(int i = ;i <= m;i ++){
scanf("%d%d%d",&l[i],&r[i],&x[i]);
b[i+n-] = x[i];
}
sort(b+,b+n+m);
cnt = unique(b+,b+n+m)-b;
for(int i = ;i < n;i ++){
int num = Find(w[i]);
add(u[i],v[i],num);
}
dfs1(,,); dfs2(,);dfs(,);
for(int i = ;i <= m;i ++){
int num = Find(x[i]);
printf("%d\n",ask(l[i],r[i],,num));
}
}

ICPC中国南昌国家邀请赛和国际丝绸之路规划大赛预选赛 I J的更多相关文章

  1. 【转帖】2011-2018年中国IPv6地址数量及国际出口带宽数走势情况[图]

    2011-2018年中国IPv6地址数量及国际出口带宽数走势情况[图] http://www.chyxx.com/industry/201910/791801.html 三亿多ipv4的地址. 接近9 ...

  2. 2019 icpc南昌全国邀请赛-网络选拔赛J题 树链剖分+离线询问

    链接:https://nanti.jisuanke.com/t/38229 题意: 给一棵树,多次查询,每次查询两点之间权值<=k的边个数 题解: 离线询问,树链剖分后bit维护有贡献的位置即可 ...

  3. ADN中国团队參加微软的Kinect全国大赛获得三等奖

    上周末我们团队參加了微软的Kinect全国大赛,我们的Kinect + Navisworks漫游荣膺三等奖   团队经理Joe写了篇详实的总结,我就直接转载了. http://blog.csdn.ne ...

  4. 【DC010沙龙年度合集】顶尖Hacking技术盛宴(文末福利)

    岁末盘点,让我们一起回顾2017年DEFCON GROUP 010带来的那些最前端的Hacker技术,体验原汁原味的mini DEFCON黑客大会,满满的干货帮你开启Hacker技术大门     &g ...

  5. TD-SCDMA风雨20年:中国3G标准的由来以及国家通信战略

    .国际电信标准是咋回事? 当年作为通信专业的学生,我曾长期困惑一个问题,为什么同一项通信技术总会有美国和欧洲两种国际标准?比如电话语音的数字化就有欧洲A律和美国u(谬)律两种. 学习后发现,两种标准的 ...

  6. 使用VNET-to-VNET连接Microsoft Azure国际版和中国版

    Microsoft Azure的VNET-to-VNET功能可以实现跨虚拟网络的VPN连接,通过VNET-to-VNET互联的两个虚拟网络可以在同一个订阅下或者隶属不同的订阅,而且可以跨数据中心.这实 ...

  7. 每个国家对应的语言Locale和国家代码对照表

    DNN3支持多语言,希望下面的语言代码与对应国家能对你有所帮助 语言代码 国家/ 地区 "" (空字符串) 无变化的文化 af 公用荷兰语 af-ZA 公用荷兰语 - 南非 sq ...

  8. 究竟谁在绑架中国的4G政策?

    2009年中国正式发放3G牌照以来,尽管在开始阶段受到了应用不足的困扰,但是随着智 能手机的迅速推广,3G移动通信也开始在中国得到了飞速的发展.就在消费者以及市场 逐步接受并广泛应用该技术之际,4G通 ...

  9. China’s movie heroes 《红海行动》展现中国英雄本色

    Recent years have seen a trend for big military movies. Whether it was last year’s British hit Dunki ...

随机推荐

  1. HTML和CSS前端教程03-CSS选择器

    目录 1. CSS定义 2. 创建CSS的三种方法 2.1. 元素内嵌(权重最高) 2.2. 文档内嵌 2.3. 外部引用 3. CSS层叠和继承 3.1. 浏览器样式 3.2. 样式表层叠 3.3. ...

  2. Messenger在MVVM模式中的应用

    Messenger在MVVM模式中的应用 Messenger在MVVM中应用的前提 我们知道在MVVM架构中,系统平台的Silverlight客户端界面开发和业务逻辑已经被分开,XAML是SL的主要部 ...

  3. [Web][DreamweaverCS6][高中同学毕业分布去向网站+服务器上挂载]一、安装与破解DreamweaverCS6+基本规划

    DreamweaverCS6安装与破解 一.背景介绍:同学毕业分布图项目计划简介 哎哎哎,炸么说呢,对于Web前端设计来说,纯手撕html部分代码实在是难受. 对于想做地图这类的就“必须”用这个老工具 ...

  4. android Q build 变化

    一 概述 android Q build变化整体上越来越严格,语法上之前能够使用的Q上将不能使用. 二 主要变化 2.1  'USER' 弃用 ‘USER’后面的值会被设置成‘nobody',andr ...

  5. SQL SELECT DISTINCT 语句

    SQL SELECT DISTINCT 语句 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值. 关键词 DISTINCT 用于返回唯一不同的值. 语法 ...

  6. AngularJS学习之旅—AngularJS 模型(四)

    1.AngularJS ng-model 指令 1.ng-model 指令用于绑定应用程序数据到 HTML 控制器(input, select, textarea)的值. 2.ng-model 指令可 ...

  7. Linux 通过编译安装apache服务以及配置

    Linux 编译安装apache服务 一.安装 1.通过编译安装,首先需要下载源代码安装包 apache下载链接:http://httpd.apache.org/download.cgi 2.解开源代 ...

  8. Filebeat使用内置的mysql模块收集日志存储到ES集群并使用kibana存储

    Filebeat内置了不少的模块,可以直接使用他们对日志进行收集,支持的模块如下: [root@ELK-chaofeng07 logstash]# filebeat modules list Enab ...

  9. Eclipse启动报错,解决办法

    打开log日志,发现如下错误.原因是修改了计算机用户名导致 !SESSION Thu Aug 30 08:55:41 CST 2018 -------------------------------- ...

  10. SQLServer之添加聚集索引

    聚集索引添加规则 聚集索引按下列方式实现 PRIMARY KEY 和 UNIQUE 约束 在创建 PRIMARY KEY 约束时,如果不存在该表的聚集索引且未指定唯一非聚集索引,则将自动对一列或多列创 ...