contest-20191021
文化课读的真不开心
回来竞赛
假人
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的更多相关文章
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- 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) ...
- 2016 Multi-University Training Contest 2 D. Differencia
Differencia Time Limit: 10000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- 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) ...
- hdu-5988 Coding Contest(费用流)
题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
- ZOJ 3703 Happy Programming Contest
偏方记录背包里的物品.....每个背包的价值+0.01 Happy Programming Contest Time Limit: 2 Seconds Memory Limit: 65536 ...
- 2012 Multi-University Training Contest 9 / hdu4389
2012 Multi-University Training Contest 9 / hdu4389 打巨表,实为数位dp 还不太懂 先这样放着.. 对于打表,当然我们不能直接打,这里有技巧.我们可以 ...
- 2014 Multi-University Training Contest 9#11
2014 Multi-University Training Contest 9#11 Killing MonstersTime Limit: 2000/1000 MS (Java/Others) ...
- 2014 Multi-University Training Contest 9#6
2014 Multi-University Training Contest 9#6 Fast Matrix CalculationTime Limit: 2000/1000 MS (Java/Oth ...
- 校际联合Contest
每次开一个坑都像是重新被碾压的预感 最近的新闻,以前很喜欢乔任梁的<复活>...然后他就死了...感觉我再多愁善感一点的话...就要悲伤逆流成河了吧... Contest 09/24(乐滋 ...
随机推荐
- 树莓派GPIO口驱动编写
一.wiringpi写法 #include <wiringPi.h> #include <stdlib.h> int main(int argc,char *argv[]) { ...
- STM32的结构和启动模式
一.STM32F10x功能模块 32位的Cortex-M3微处理器: 可嵌套的向量中断控制器(NVIC)和60个可屏蔽中断且有16个可编程优先级: 内嵌内存: FLASH:最大512K字节 STAM: ...
- python 的按位与、或、异或 运算
符号 描述 运算规则 by MoreWindows & 与 两个位都为1时,结果才为1 (统计奇数) | 或 两个位都为0时,结果才为0 ...
- linux查看java jdk jre安装路径和设置环境变量
一. 查看java jdk安装路径和设置环境变量 windows: set java_home:查看JDK安装路径 java -version:查看JDK版本 linux: whereis java ...
- 极简Vue的异步组件函数
export default new Router({ routes: [ { path: '/live', name: 'live', component: () => import('@/v ...
- centos 安装 Lamp(Linux + Apache + PHP) 并安装 phpmyadmin
来源:http://www.laozhe.net/302.html 一般情况下,安装的都是最新的正式版,除非你有特殊需求,要安装指定的版本,本文暂不讨论.从最基础的开始,一点点完成一个可用的 Linu ...
- sed 对文件进行操作
首先我们想不进入一个文件 对文件进行操作 那么久需要用到sed了 在某个变量之前添加内容: sed -i 's/原内容/要添加内容/g' 文件名 sed -i 's/原内容/要添加内容&/' ...
- vue中按需引入mint-UI报Error: .plugins[3][1] must be an object, false, or undefined
{ "presets": ["@babel/preset-env", "@babel/preset-react"], "plugi ...
- jmeter 函数学习
https://jmeter.apache.org/usermanual/functions.html#__threadNum
- Kotlin 和 Flutter 对于开发者究竟意味着什么?
更多阿里P7架构进阶学习视频:阿里P7Android架构进阶学习视频回放近些年来,编程语言流行度的变化其实不大,在 TIOBE 编程语言排行榜上,Java.C.C++ 固若金山,也就只有 Python ...