• Atcoder arc085


    C:HSI

    期望模型,不想说。

     1 #include<cstdio>
     2 using namespace std;
     3 typedef long long ll;
     4 int main()
     5 {
     6    int n,m;
     7    scanf("%d%d",&n,&m);
     8    printf("%lld
    ",(ll)((n-m)*100+m*1900)*(1<<m));
     9    return 0;
    10 }

    D:ABS

    f[i][j]表示第i轮,X在i,Y在j,玩到最后的差绝对值。下一次由Y先手,取所有可以的转移中的最小值。

    g[i][j]表示第i轮,Y在i,X在j,玩到最后的差绝对值。下一次由X先手,取所有可以的转移中的最大值。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int N=2005;
     5 int n,z,w,a[N],ans,Mn_g[N],Mx_f[N],f[N][N],g[N][N];
     6 int main()
     7 {
     8    scanf("%d%d%d",&n,&z,&w);
     9    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    10    a[0]=w;
    11    for (int i=0;i<n;i++) f[n][i]=g[n][i]=Mx_f[i]=Mn_g[i]=abs(a[n]-a[i]);
    12    for (int i=n-1;i>=0;i--)
    13      for (int j=0;j<i;j++)
    14      {
    15        if (i) f[i][j]=Mn_g[i],Mx_f[j]=max(Mx_f[j],f[i][j]);
    16        if (j) g[i][j]=Mx_f[i],Mn_g[j]=min(Mn_g[j],g[i][j]);
    17      }
    18    for (int i=1;i<=n;i++) ans=max(ans,f[i][0]);
    19    printf("%d
    ",ans);
    20    return 0;
    21 }

    E:MUL

    题意:n个宝石,有价值ai,可以为负。你可以打碎若干宝石和其所有标号有倍数关系的宝石。问剩下的宝石最大价值和?

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 typedef long long ll;
     7 const int N=105;
     8 const ll inf=1ll<<60;
     9 int cnt=1,head[N],Head[N],n,dis[N],S,T,x;
    10 ll ans,tmp;
    11 queue<int> q;
    12 struct node{int to,next;ll w;}num[N*N*2];
    13 void add(int x,int y,ll w)
    14 {num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;head[x]=cnt;
    15 num[++cnt].to=x;num[cnt].next=head[y];num[cnt].w=0;head[y]=cnt;}
    16 int bfs()
    17 { 
    18    memset(dis,0,sizeof(dis));dis[S]=1;
    19    q.push(S);
    20    while (!q.empty())
    21    {
    22      int now=q.front();q.pop();
    23      for (int i=head[now];i;i=num[i].next)
    24        if (num[i].w&&!dis[num[i].to])
    25           q.push(num[i].to),dis[num[i].to]=dis[now]+1;
    26     }
    27     return dis[T];
    28 }
    29 ll dfs(int x,ll mm)
    30 { 
    31   ll tmp=mm;
    32   if (x==T) return mm;
    33   for (int &i=Head[x];i&&tmp;i=num[i].next)
    34     if (dis[num[i].to]==dis[x]+1)
    35     {
    36        ll t=dfs(num[i].to,min(num[i].w,tmp));
    37        tmp-=t;num[i].w-=t;num[i^1].w+=t;
    38     }
    39   return mm-tmp;
    40 }
    41 void dinic()
    42 {
    43    while (bfs())
    44    {
    45      memcpy(Head,head,sizeof(head));
    46      while (tmp=dfs(S,inf)) ans-=tmp;
    47    }
    48 }
    49 int main()
    50 {
    51   scanf("%d",&n);S=n+1;T=S+1;
    52   for (int i=1;i<=n;i++) 
    53   {
    54      scanf("%d",&x);
    55      if (x<0) add(S,i,-x);else add(i,T,x),ans+=x;
    56   }
    57   for (int i=1;i<=n;i++)
    58     for (int j=i+i;j<=n;j+=i) add(i,j,inf);
    59   dinic();
    60   printf("%lld
    ",ans);
    61   return 0;
    62 }

    最小割建模(又忘记套路了真是该打)

    S部设为不选,T部为选。权值为负的点向S连容量为-w的边,权值为正的点向T连容量为w的边。这里的容量相当于是割掉这条边的代价。

    对于所有有倍数关系的点,小的向大的连inf的边。ans一开始为所有正权边的权值和。

    比如对于i和2i,S-i,i-2i,2i-T。那么割掉i-2i,就是不选i而选2i,不可能。割掉S-i,就是都保留,那么ans-=w[i]。割掉2i-T,就是都不保留,那么ans-=w[2i]。所以最大权值也就是一个最小割的问题啦。

    建模方法:分为选和不选两部分点,把边的容量设为代价,通过正负的约束来使得要求的是最小割,ans一开始统计全部保留和T点(保留点)连边的价值和。

    F:NRE

    题意:给你若干个区间,你可以从中选取部分来使得一整个区间变成1。

    初始序列为A,问进行一些操作后,和B的最少不同位?

    n<=20W。

     1 #include<bits/stdc++.h>
     2 #define mid ((l+r)>>1)
     3 using namespace std;
     4 const int inf=0x3f3f3f3f;
     5 const int N=200005;
     6 int T[N<<2],tag[N<<2],n,a[N],sum0[N],sum1[N],Q,head;
     7 struct node{int l,r;}q[N];
     8 bool operator < (const node &A,const node &B)
     9 {return A.l<B.l||A.l==B.l&&A.r<B.r;}
    10 void down(int k)
    11 {
    12   if (tag[k])
    13   { 
    14     tag[k<<1]+=tag[k];tag[k<<1|1]+=tag[k];
    15     T[k<<1]+=tag[k];T[k<<1|1]+=tag[k];
    16     tag[k]=0;
    17   }
    18 }
    19 void ins(int k,int l,int r,int x,int y)
    20 {
    21   if (l==r) {T[k]=min(T[k],y);return;}
    22   down(k);
    23   if (x<=mid) ins(k<<1,l,mid,x,y);
    24   else ins(k<<1|1,mid+1,r,x,y);
    25   T[k]=min(T[k<<1],T[k<<1|1]);
    26 }
    27 void add(int k,int l,int r,int L,int R,int x)
    28 {
    29    if (L<=l&&r<=R) {T[k]+=x;tag[k]+=x;return;}
    30    down(k);
    31    if (L<=mid) add(k<<1,l,mid,L,R,x);
    32    if (R>mid) add(k<<1|1,mid+1,r,L,R,x);
    33    T[k]=min(T[k<<1],T[k<<1|1]);
    34 }
    35 int qry(int k,int l,int r,int L,int R)
    36 {
    37    if (L<=l&&r<=R) return T[k];
    38    down(k);int ans=inf;
    39    if (L<=mid) ans=min(ans,qry(k<<1,l,mid,L,R));
    40    if (R>mid) ans=min(ans,qry(k<<1|1,mid+1,r,L,R));
    41    return ans;
    42 }
    43 int main()
    44 {
    45   scanf("%d",&n);
    46   for (int i=1;i<=n;i++) 
    47   {
    48      scanf("%d",&a[i]);sum0[i]=sum0[i-1];sum1[i]=sum1[i-1];
    49      if (!a[i]) sum0[i]++;else sum1[i]++;
    50   }
    51   scanf("%d",&Q);
    52   for (int i=1;i<=Q;i++) scanf("%d%d",&q[i].l,&q[i].r);
    53   sort(q+1,q+Q+1);
    54   head=1;memset(T,inf,sizeof(T));
    55   ins(1,0,n,0,0);
    56   for (int i=1;i<=n;i++)
    57   {
    58     while (head<=Q&&q[head].l==i) ins(1,0,n,q[head].r,qry(1,0,n,0,q[head].r)),head++;
    59     if (a[i]) add(1,0,n,0,i-1,1);else add(1,0,n,0,i-1,-1);
    60   }
    61   printf("%d
    ",qry(1,0,n,0,n)+sum0[n]);
    62   return 0;
    63 }

     线段树优化dp

    我们要求的是(0,1)+(1,0)的数量,也就是(0,1)+(0/1,0)-(0,0)。那么(0/1,0)是固定的,即要使得(0,1)-(0,0)最小。1的覆盖也就是不计算一些位置的贡献。

    哇这个dp思路超级巧妙。dp[i][j]表示前i个数确定,当前最后一个1在j的最小(0,1)-(0,0)。

    从小到大枚举i,对于一条左端点在i的线段[i,r],dp[i][r]=min(dp[i-1][k]),k<=r。(因为i之后都是1,相当于只有前i-1位确定即可。而且如果k>r,那么之前那条线段一定包含[i,r],dp[i][r]的更新跟它就没有什么关系了,况且根据定义最后一个1就出界了),其他没有更改的和dp[i-1]一样。

    此时落点>=i的线段一定覆盖了i点(因为线段的左端点<=i),因而我们需要对于所有dp[i][0~i-1]都更改为前i个数确定的状态,由第i个数的0/1决定-1/+1。区间最小值和区间加用线段树实现。时间复杂度O(nlogn)。

  • 相关阅读:
    数组相关常见的三种错误
    JMeter连接MYSQL数据库并进行操作详解
    JMeter实现动态关联——两个接口在不同的线程组
    Android : kernel中添加虚拟文件节点
    Android O : 系统原生锁屏密码位数限制及自动检查
    Android O : DNS列表获取及IPv4/IPv6优先级修改
    Android 打印调用栈的方法
    Android TV : 系统分区配置及增加私有分区
    Android TV : Mstar平台Audio Path及声音曲线配置
    Android TV : Mstar平台 GPIO 调试
  • 原文地址:https://www.cnblogs.com/Scx117/p/8868755.html
Copyright © 2020-2023  润新知