google kickstart 2018 D A.candies

题意

n个糖果之中找出一段区间,使得甜度和 < d且其中甜度为奇数的糖果数 < o
小数据限定甜度是递增d

思路

小范围数据
两个指针:对每个l,都使得r为符合条件的,距离l最远的那个值
更新到左指针为l+1的时候只需要从r开始再向后寻找当前的最右
Problem A Analysis
https://code.google.com/codejam/contest/6364486/dashboard#s=a&a=0

代码

写得好乱,自己都不是很清楚了(捶

#include <algorithm>
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
typedef long long ll;

const int INF = 0x7f7f7f7f;
const int maxn = 500000 + 10;

int n, o;
ll d;
int x1, x2, a, b, c, mod, l;
ll sweet[ maxn ];
ll ss;
int so;

void solve ( int ks ) {
    int l = 0, r = 0;
    ss = 0, so = 0; //和的值,奇数的个数
    ll ans = -1;
    bool flag = false; //是否找到过符合条件的区间
    for ( l = 0; l < n; ++l ) {
        r = max ( r, l );
        while ( ss + sweet[ r ] <= d && ( sweet[ r ] & 1 ? so + 1 : so ) <= o && r < n ) {
            ss = ss + sweet[ r ];
            so = sweet[ r ] & 1 ? so + 1 : so;
            r++;
            flag = true;
        }
        ans = max ( ans, ss );
        ss = max ( (ll)0, ss - sweet[ l ] );
        so = max ( 0, sweet[ l ] & 1 ? so - 1 : so );
    }
    if ( flag )
        printf ( "Case #%d: %lld\n", ks, ans );
    else
        printf ( "Case #%d: IMPOSSIBLE\n", ks );
}

int main () {
#ifdef LOCAL
    // freopen ( "in", "r", stdin );
    freopen ( "/home/aria/Downloads/A-small-practice.in", "r", stdin );
    freopen ( "out", "w", stdout );
#endif
    int T;
    scanf ( "%d", &T );
    for ( int ks = 1; ks <= T; ++ks ) {
        scanf ( "%d%d%lld", &n, &o, &d );
        scanf ( "%d%d%d%d%d%d%d", &x1, &x2, &a, &b, &c, &mod, &l );

        sweet[ 0 ] = x1, sweet[ 1 ] = x2;
        for ( int i = 2; i < n; ++i )
            sweet[ i ] = ( a * sweet[ i - 1 ] % mod + b * sweet[ i - 2 ] % mod + c ) % mod + l;
        // sweet[ 0 ] = 1, sweet[ 1 ] = 1, sweet[ 2 ] = 2;
        /* for ( int i = 0; i < n; ++i )
             printf ( "%lld ", sweet[ i ] );
         printf ( "\n\n" );
         */

        solve ( ks );
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值