文化课读的真不开心

回来竞赛

假人

sol

根据不等式有 abs(a-b)+abs(b-c)>=abs(a-c)

那么每一个都会选。

可以发现每一段只会选在端点上(否则移到端点更优)。

那么dp f[i][0/1]表示前i个选在上/下端点的最大值。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100005
using namespace std;
int n,a[maxn][];
long long s1,s2,f[maxn][];
int main()
{
freopen("arachne.in","r",stdin);
freopen("arachne.out","w",stdout);
cin>>n;
for(int i=;i<=n;i++)scanf("%d%d",&a[i][],&a[i][]);
for(int i=;i<=n;i++){
s1=max(abs(a[i][]-a[i-][])+f[i-][],abs(a[i][]-a[i-][])+f[i-][]);
s2=max(abs(a[i][]-a[i-][])+f[i-][],abs(a[i][]-a[i-][])+f[i-][]);
f[i][]=s1;f[i][]=s2;
}
cout<<max(f[n][],f[n][])<<endl;
return ;
}

愚者

sol

考虑把点按权值大到小加入,用并查集维护联通快大小,那么每次加入的一定是最小值。
把式子展开,发现它形如y=kx+b.

每次得到一组(k,b)

对这些直线构出下凸壳,线性处理ans

100%数据范围小于部分分范围是什么鬼,差评投诉

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 300005
#define ll long long
using namespace std;
int n,m,Q,head[maxn],tot;
int f[maxn],sz[maxn],flag[maxn];
ll ans[maxn];
struct line{
ll a,b;
}s[maxn],li[maxn],l[maxn],q[maxn];
struct node{
int v,nex;
}e[maxn];
void add(int t1,int t2){
e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
}
bool cmp(line A,line B){return A.a>B.a;}
bool dmp(line A,line B){return A.a<B.a||(A.a==B.a&&A.b<B.b);}
int getf(int k){return f[k]==k?k:f[k]=getf(f[k]);}
double C(line A,line B){
return (double)(B.b-A.b)/(double)(A.a-B.a);
}
int main()
{
cin>>n>>m>>Q;
for(int i=;i<=n;i++){
scanf("%lld",&s[i].a),s[i].b=i;
f[i]=i;sz[i]=;
}
for(int i=,t1,t2;i<=m;i++){
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
}
for(int i=;i<=Q;i++)scanf("%lld",&q[i].a),q[i].b=i;
sort(s+,s+n+,cmp);
for(int x=;x<=n;x++){
flag[s[x].b]=;
for(int i=head[s[x].b];i;i=e[i].nex){
if(flag[e[i].v]){
int fv=getf(e[i].v);
if(fv!=s[x].b)f[fv]=s[x].b,sz[s[x].b]+=sz[fv];
}
}
li[x].a=sz[s[x].b];li[x].b=s[x].a*sz[s[x].b];
}
sort(li+,li+n+,dmp);sort(q+,q+Q+,dmp);
int j=;
int tp=;
for(int i=;i<=n;i++){
if(li[i].a==li[i+].a&&li[i].b<=li[i+].b)continue;
while(tp>&&C(l[tp-],l[tp])>C(l[tp-],li[i]))tp--;
l[++tp]=li[i];
}
for(int i=;i<=tp;i++){ double cr;
if(i<tp)cr=C(l[i],l[i+]);
else cr=1e7;
for(;j<=Q&&(double)q[j].a<cr;j++)ans[q[j].b]=l[i].a*q[j].a+l[i].b;
}
for(int i=;i<=Q;i++)printf("%lld\n",ans[i]);
return ;
}

拙者

sol

40% 贪心从前往后再从后往前取即可

20% (1,2) 线段树维护最小值

100%

考虑第一次从左往右的修改。

把+1看成向上,-1看成向下,这个序列看成折现

每一个点的最终位置是他减他之前的最小值,也就是把他之前的最小值提到0(水平位置)。

那么考虑维护区间最大值,最小值,极差,总和。

从前往后是答案是 max(-最小值,0)

从前往后是max(极差-(sum-Min))

极差就是最高点,sum-Min为最后一个点的位置。

60%

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 200005
#define mid ((l+r)>>1)
#define ls k<<1
#define rs k<<1|1
using namespace std;
int n,q,a[maxn],b[maxn];
char ch[maxn];
struct node{
int v,bj;
}tr[maxn*];
node wh(node A,node B){
node C;
C.sum=A.sum+B.sum;
C.mi=min(A.mi,A.sum+B.mi);
C.ma=max(A.ma,A.sum+B.ma);
C.d=max(max(A.d,B.d),A.sum+B.ma-A.mi);
return C;
}
void build(int k,int l,int r){
if(l==r){tr[k].sum=tr[k].ma=tr[k].mi=a[l];tr[k].d=;return;}
build(ls,l,mid);build(rs,mid+,r);
tr[k]=wh(tr[ls],tr[rs]);
}
void upd(int k,int l,int r,int pl){
if(l==r){
tr[k].sum=tr[k].ma=tr[k].mi=a[l];
return;
}
if(pl<=mid)upd(ls,l,mid,pl);
else upd(rs,mid+,r,pl);
tr[k]=wh(tr[ls],tr[rs]);
}
node ask(int k,int l,int r,int li,int ri){
if(l>=li&&r<=ri)return tr[k];
if(ri<=mid)return ask(ls,l,mid,li,ri);
if(li>mid)return ask(rs,mid+,r,li,ri);
return wh(ask(ls,l,mid,li,ri),ask(rs,mid+,r,li,ri));
} void wh(int k){
tr[k].v=min(tr[ls].v,tr[rs].v);
}
void build(int k,int l,int r){
if(l==r){tr[k].v=b[l];return;}
build(ls,l,mid);build(rs,mid+,r);
wh(k);
}
void upd(int k,int v){
tr[k].bj+=v;tr[k].v+=v;
}
void down(int k){
if(tr[k].bj!=){
upd(ls,tr[k].bj);upd(rs,tr[k].bj);
tr[k].bj=;
}
}
void add(int k,int l,int r,int li,int ri,int v){
if(l>=li&&r<=ri){
upd(k,v);return;
}
down(k);
if(li<=mid)add(ls,l,mid,li,ri,v);
if(ri>mid)add(rs,mid+,r,li,ri,v);
wh(k);
}
int ask(int k,int l,int r,int li,int ri){
if(li==)return ;
if(l>=li&&r<=ri)return tr[k].v;
down(k);
int Min=1e9;
if(li<=mid)Min=min(Min,ask(ls,l,mid,li,ri));
if(ri>mid)Min=min(Min,ask(rs,mid+,r,li,ri));
return Min;
}
int main()
{
cin>>n;scanf(" %s",ch+);
for(int i=;i<=n;i++){
a[i]=(ch[i]=='(')?:-;
}
if(n<=){
scanf("%d",&q);
for(int I=,op,l,r;I<=q;I++){
scanf("%d",&op);
if(op==)scanf("%d",&l),a[l]=-a[l];
else {
scanf("%d%d",&l,&r);
if(op==){
int tmp=,ans=;
for(int i=l;i<=r;i++){
b[i]=a[i];
if(tmp+b[i]<)b[i]=,ans++;
tmp+=b[i];
}
printf("%d\n",ans);
}
else {
int tmp=,ans=;
for(int i=l;i<=r;i++){
b[i]=a[i];
if(tmp+b[i]<)b[i]=,ans++;
tmp+=b[i];
}
tmp=;
for(int i=r;i>=l;i--){
if(tmp+b[i]<)b[i]=,ans++;
tmp+=b[i];
}
printf("%d\n",ans);
}
}
}
}
else { for(int i=;i<=n;i++)b[i]=b[i-]+a[i];
build(,,n);
scanf("%d",&q);
for(int I=,op,l,r;I<=q;I++){
scanf("%d",&op);
if(op==){
scanf("%d",&l),add(,,n,l,n,-*a[l]);
a[l]=-a[l];
}
else {
scanf("%d%d",&l,&r);
if(op==){
int x=ask(,,n,l-,l-),y=ask(,,n,l,r);
printf("%d\n",max(x-y,));
}
}
}
}
return ;
}

100%

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define mid ((l+r)>>1)
#define ls k<<1
#define rs k<<1|1
#define maxn 200005
using namespace std;
int n,q,a[maxn];
char ch[maxn];
struct node{
int ma,mi,sum,d;
}tr[maxn*]; node wh(node A,node B){
node C;
C.sum=A.sum+B.sum;
C.mi=min(A.mi,A.sum+B.mi);
C.ma=max(A.ma,A.sum+B.ma);
C.d=max(max(A.d,B.d),A.sum+B.ma-A.mi);
return C;
}
void build(int k,int l,int r){
if(l==r){tr[k].sum=a[l];tr[k].ma=max(a[l],);tr[k].mi=min(a[l],);tr[k].d=;return;}
build(ls,l,mid);build(rs,mid+,r);
tr[k]=wh(tr[ls],tr[rs]);
}
void upd(int k,int l,int r,int pl){
if(l==r){
tr[k].sum=a[l];tr[k].ma=max(a[l],);tr[k].mi=min(a[l],);tr[k].d=;
tr[k].d=;
return;
}
if(pl<=mid)upd(ls,l,mid,pl);
else upd(rs,mid+,r,pl);
tr[k]=wh(tr[ls],tr[rs]);
}
node ask(int k,int l,int r,int li,int ri){
if(l>=li&&r<=ri)return tr[k];
if(ri<=mid)return ask(ls,l,mid,li,ri);
if(li>mid)return ask(rs,mid+,r,li,ri);
return wh(ask(ls,l,mid,li,ri),ask(rs,mid+,r,li,ri));
}
int main()
{
cin>>n;scanf(" %s",ch+);
for(int i=;i<=n;i++){
a[i]=(ch[i]=='(')?:-;
}
build(,,n);
scanf("%d",&q);int tp=;
for(int I=,op,l,r;I<=q;I++){
scanf("%d",&op);
if(op==){
scanf("%d",&l);a[l]=-a[l];
upd(,,n,l);
}
else {
scanf("%d%d",&l,&r);
if(op==){
node ans=ask(,,n,l,r);
printf("%d\n",max(-ans.mi,));
}
else {
node ans=ask(,,n,l,r);
int sum=max(-ans.mi,)+max(ans.d-(ans.sum-ans.mi),);
printf("%d\n",sum);
}
}
}
return ;
}
/*
4
(())
1
3 1 4
*/

注意事项:

1.若查询l-1要特判0

2.修改a[l]外面也要改

3.区间最小值、最大值都要和0取,因为基准是0

contest-20191021的更多相关文章

  1. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  2. hdu 4946 2014 Multi-University Training Contest 8

    Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. 2016 Multi-University Training Contest 2 D. Differencia

    Differencia Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  4. 2016 Multi-University Training Contest 1 G. Rigid Frameworks

    Rigid Frameworks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  5. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  6. ZOJ 3703 Happy Programming Contest

    偏方记录背包里的物品.....每个背包的价值+0.01 Happy Programming Contest Time Limit: 2 Seconds      Memory Limit: 65536 ...

  7. 2012 Multi-University Training Contest 9 / hdu4389

    2012 Multi-University Training Contest 9 / hdu4389 打巨表,实为数位dp 还不太懂 先这样放着.. 对于打表,当然我们不能直接打,这里有技巧.我们可以 ...

  8. 2014 Multi-University Training Contest 9#11

    2014 Multi-University Training Contest 9#11 Killing MonstersTime Limit: 2000/1000 MS (Java/Others)   ...

  9. 2014 Multi-University Training Contest 9#6

    2014 Multi-University Training Contest 9#6 Fast Matrix CalculationTime Limit: 2000/1000 MS (Java/Oth ...

  10. 校际联合Contest

    每次开一个坑都像是重新被碾压的预感 最近的新闻,以前很喜欢乔任梁的<复活>...然后他就死了...感觉我再多愁善感一点的话...就要悲伤逆流成河了吧... Contest 09/24(乐滋 ...

随机推荐

  1. 【Flutter学习】之 Flutter 的生命周期

    一,概述 Flutter 的生命周期分为两个部分: Widget 的生命周期 App 的生命周期 二,Widget 的生命周期 Flutter 里的 Widget 分为 StatelessWidget ...

  2. feign学习

    feign集成了ribbon,只需要新建接口加注解即可 <!--feign相关--> <dependency> <groupId>org.springframewo ...

  3. svn服务端安装、迁移教程、Eclipse切换svn连接库

    svn服务端安装.迁移教程.Eclipse切换svn连接库 安装教程 1.下载svn服务端安装程序 2.运行程序,安装 这里端口号根据自己定义,避免与其他程序冲突 到这里就安装完成 迁移教程 这里举例 ...

  4. 说下vue工程中代理配置proxy

    这个代理配置不需要后台进行ngnix代理跳转了,前端可以做.在vue.config.js文件中进行配置,如下: module.exports = { publicPath: process.env.V ...

  5. python 网络编程:socket

    在学习socket之前,我们先复习下相关的网络知识. OSI七层模型:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.OSI七层模型是由国际标准化组织ISO定义的网络的基本结构,不仅包括一 ...

  6. 网络-Docker 提供的几种原生网络和自定义网络(11)

    Docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 host 的网络,本章重点讨论前一种 Docker 安装时会自动在 host 上创建三个网络,我们可用 docker netwo ...

  7. win10配置 samba

    一.先確認Linux中smb正確配置可以使用命令smbclient -L //localhost/ 二.win10配置1.打開win10對smb1.0/cifs檔共用支援2.本地群組原則編輯,修改如下 ...

  8. 并发和Tomcat线程数

    转自 http://zhanjindong.com 最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多 ...

  9. HTML-参考手册: HTML ISO-8859-1

    ylbtech-HTML-参考手册: HTML ISO-8859-1 1.返回顶部 1. HTML ISO-8859-1 参考手册 现代的浏览器支持的字符集: ASCII 字符集 标准 ISO 字符集 ...

  10. Windows 8.1 PLSQL_32连接到RHEL6.1 Oracle10gr2_64

    目录 目录 系统环境 连接Oracle Server 系统环境 操作系统 Windows 8.1 RHEL6.1 软件 Oracle10gr2 PL/SQL instantclient-basic-w ...