文化课读的真不开心

回来竞赛

假人

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. SCP-bzoj-1019

    项目编号:bzoj-1019 项目等级:Safe 项目描述: 戳这里 特殊收容措施: 对于一个hanoi,知道了各种移动操作的优先级,也就确定了方案.可以证明对于盘子数为N的hanoi,任意移动方案都 ...

  2. paper 135:关于C#泛型的一些讲解

    计划着要用一个月的时间把  C#语言Windows程序设计 搞定,现在是零零散散的知识点,日积月累吧!朋友们,看这里咯~呵呵 原文地址:http://www.blogjava.net/Jack2007 ...

  3. MySQL coalesce函数用法说明(转)

    在mysql中,其实有不少方法和函数是很有用的,一个叫coalesce的,作用是将返回传入的参数中第一个非null的值,比如 SELECT COALESCE(NULL, NULL, 1); -- Re ...

  4. Tomcat_startup

    @echo off echo 执行开始时间 date/t time/t echo *********************************************** echo 清除Tomc ...

  5. camunda流程实例启动的一些简单操作

    public class ZccRuntimeService { RuntimeService runtimeService; RepositoryService repositoryService; ...

  6. P4363 [九省联考2018]一双木棋

    题面 这种搜索要把后继状态都跑出来之后取Min/Max 也就是回溯的时候进行操作 记得用hash进行记忆化(用map不开O2会TLE) #include<iostream> #includ ...

  7. Python值正则表达式(RE)

    要想在Python中使用正则表达式,首先要引入模块: import re . 匹配任意一个 +   匹配至少一个 * 匹配0个至多个 ? 1个或0个(可有可无) - 表范围 \ 转义 ^   在首 $ ...

  8. ArcGis 创建Annotation注记要素类、添加注记要素 并加载到Activeview AO C#

    AO中一般有两种方式存储图面注记元素,一种使用TextElement,它是文档级的元素,编辑后要通过文档(mxd)保存:另一种是使用Annotation要素类,它是一个独立的要素类(featurecl ...

  9. 算法竞赛模板 AC自动机

    AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思 ...

  10. node升级

    1. 全局安装n: npm i -g n; 2.查看n版本: n -v 3.查看node版本: node -v 4.安装node最新稳定版本: n stable 5.安装node指定版本: n 9.1 ...