zoukankan      html  css  js  c++  java
  • XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem D. Great Again

    题目:

    Problem D. Great Again
    Input file: standard input
    Output file: standard output
    Time limit: 2 seconds
    Memory limit: 512 megabytes
    The election in Berland is coming. The party United Berland is going to use its influence to win them
    again. The crucial condition for the party is to win the election in the capital to show the world that the
    protests of opposition in it are inspired by external enemies.
    The capital of Berland consists of only one long road with n people living alongside it. United Berland
    has a lot of informers, so they know for each citizen whether he is going to attend the election, and if yes,
    who is he going to vote for: the ruling party or the opposition.
    United Berland has a vast soft power, so they can lobby the desired distribution of districts. Every district
    should be a consecutive segment of the road of length between l and r inclusive. Each citizen must be
    assigned to exactly one district. The votes are counted in each district separately, and the parties receive
    one point for each district, where it receives strictly more votes than the other party. If the parties got
    equal result in this district, no one gets its vote. United Berland is going to create the distribution that
    maximizes the difference of its points and points of the opposition, and you are asked to compute this
    value.
    Input
    The first line of the input contains three positive integers n, l, r (1 n 300 000, 1 l r n) — the
    number of citizens in the capital, the lower and the upper bounds on the possible length of a district.
    The second line contains n integers a1; a2; : : : ; an (ai 2 f-1; 0; 1g), denoting the votes of the citizens. 1
    means vote for the ruling party, -1 means vote for opposition, 0 means that this citizen is not going to
    come to the elections.
    Output
    If there is no way to divide the road into districts of lengths between l and r, print “Impossible” (without
    quotes).
    Otherwise, print one integer — the maximum possible difference between the scores of United Berland
    and the opposition in a valid distribution of citizens among voting districts.
    Examples

    standard input standard output
    5 1 5
    1 -1 0 -1 1
    1
    5 2 3
    -1 1 -1 1 -1
    -1
    6 1 1
    1 -1 -1 -1 -1 -1
    -4
    5 3 3
    1 1 1 1 1
    Impossible


    Note
    In the first sample, the optimal division of districts is f1g; f2; 3; 4g; f5g.
    In the second sample, the optimal division is f1; 2g; f3; 4; 5g.
    In the third sample, there is only one possible division.
    There is no way to divide 5 in segments of length 3, so in the fourth sample the answer is “Impossible”.

    思路:

      DP:dp[i]=max{dp[j]+f[j+1][i]},(i-l+1<=j<=l-r+1)

      现在难点是怎么做到快速转移。(f[j+1][i]表示区间[j+1,i]的贡献)

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define MP make_pair
     6 #define PB push_back
     7 typedef long long LL;
     8 typedef pair<int,int> PII;
     9 const double eps=1e-8;
    10 const double pi=acos(-1.0);
    11 const int K=3e5+7;
    12 const int mod=1e9+7;
    13 
    14 int n,tl,tr,py,sum[K],dp[K],v[K*20];
    15 priority_queue<PII>q[K*4];
    16 int update(int o,int l,int r,int pos,int x)
    17 {
    18     if(l==r) return v[o]=x;
    19     int mid=l+r>>1;
    20     if(pos<=mid) update(o<<1,l,mid,pos,x);
    21     else update(o<<1|1,mid+1,r,pos,x);
    22     v[o]=max(v[o<<1],v[o<<1|1]);
    23 }
    24 int query(int o,int l,int r,int nl,int nr)
    25 {
    26     if(l==nl&&r==nr) return v[o];
    27     int mid=l+r>>1;
    28     if(nr<=mid) return query(o<<1,l,mid,nl,nr);
    29     else if(nl>mid) return query(o<<1|1,mid+1,r,mid+1,nr);
    30     return max(query(o<<1,l,mid,nl,mid),query(o<<1|1,mid+1,r,mid+1,nr));
    31 }
    32 void add(int x)
    33 {
    34     if(x<0) return ;
    35     int fx=sum[x]+n+2;
    36     if(q[fx].size()==0||q[fx].top().first<dp[x])
    37         update(1,1,2*n+2,fx,dp[x]);
    38     q[fx].push(MP(dp[x],x));
    39 }
    40 void del(int x)
    41 {
    42     if(x<0) return;
    43     int fx=sum[x]+n+2;
    44     while(q[fx].size()&&q[fx].top().second<=x) q[fx].pop();
    45     if(q[fx].size()==0)
    46         update(1,1,2*n+2,fx,-mod);
    47     else
    48         update(1,1,2*n+2,fx,q[fx].top().first);
    49 }
    50 int main(void)
    51 {
    52     scanf("%d%d%d",&n,&tl,&tr);
    53     for(int i=1,mx=n*8+2;i<=mx;i++) v[i]=-mod;
    54     for(int i=1,x;i<=n;i++) scanf("%d",&x),sum[i]=sum[i-1]+x;
    55     for(int i=1;i<=n;i++)
    56     {
    57         del(i-tr-1);add(i-tl);
    58         int q1=query(1,1,2*n+2,1,sum[i]-1+n+2);
    59         int q2=query(1,1,2*n+2,sum[i]+n+2,sum[i]+n+2);
    60         int q3=query(1,1,2*n+2,sum[i]+1+n+2,n+n+2);
    61         if(q1==q2&&q2==q3&&q1==-mod)
    62             dp[i]=-mod;
    63         else
    64             dp[i]=max(max(q1+1,q2),q3-1);
    65     }
    66     if(dp[n]==-mod) printf("Impossible
    ");
    67     else printf("%d",dp[n]);
    68     return 0;
    69 }
  • 相关阅读:
    timestamp与timedelta,管理信息系统概念与基础
    datetime处理日期和时间
    中文词频统计
    文件方式实现完整的英文词频统计实例
    组合数据类型练习,英文词频统计实例上
    英文词频统计预备,组合数据类型练习
    加载静态文件,父模板的继承和扩展
    开始Flask项目
    夜间模式的开启与关闭,父模板的制作
    完成登录与注册页面的前端
  • 原文地址:https://www.cnblogs.com/weeping/p/7284356.html
Copyright © 2011-2022 走看看