2015-9-13 NOIP模拟赛 by hzwer

好老的题了,但是还是很有做头的。

总结

  1. 不吸氧看来确实是没法用stl的啊
  2. SPFA没认真学,觉得有堆优化Dijkstra就天下无敌了,今天负边权教我做人
  3. 于是苦逼的只有180分
  4. 第一题我看错了,想了10分钟,本来打算打暴力50分,然后又看对了。 /(ㄒoㄒ)/~~

小奇挖矿

题目分析

我们发现这道题每个操作只对其后面又影响,然后我们想到DP要求的无后效性,于是我们直接倒着DP一下就好了。
(最重要的是这道题有取东西的顺序)

代码

#include <cstdio>
#include <iostream>
using namespace std;

#define forn(i) for(int i=1;i<=n;++i)

const int maxn = 1e5 + 10;
int opt[maxn], a[maxn];

int main() {
    freopen("explo.in","r",stdin);
    freopen("explo.out","w",stdout);
    double n, k, c, w;
    cin >> n >> k >> c >> w;
    forn(i) cin >> opt[i] >> a[i];
    double p_1 = 1-0.01*k;
    double p_2 = 1+0.01*c;
    double ans = 0;
    for (int i = n; i; -- i)
        if (opt[i] & 1) ans = max(ans, ans * p_1 + a[i]);
        else            ans = max(ans, ans * p_2 - a[i]);
    printf("%.2lf", ans*w);
    return 0;
}

小奇的数列

题目分析

emmm,这道题暴力都可以70分。我怕不吸氧set过不了,于是写了个70的部分分,然后写了个stl版正解
70pts: 首先根据抽屉原理,如果询问长度 \(\ge q\) 那就必有前缀和模\(q\)相等,或者这个数本身被\(q\)整除,然后因为\(q \le 200\)直接\(n ^ 2\)暴力

100pts: 考虑已经定下来一端,我们只需要寻找另外一段,是的他们的差值最小就行了,于是自然的写出二分。维护的话,考虑平衡树,或者set都可以。

代码

set

#include <cstdio>
#include <iostream>
#include <set>
using namespace std;
typedef long long qword;
#define pb push_back

#define forn(i) for(int i=1;i<=n;++i)
#define rep(i,s,t) for(int i=(int)(s);i<=(int)(t);++i)

int n, m;
const int maxn = 5e5 + 10;
int a[maxn];
qword sum[maxn];

inline void Init() {
    cin >> n >> m;
    forn(i) cin >> a[i];
    forn(i) sum[i] = sum[i - 1] + a[i];
}

qword mod(qword x, int p) {
    x %= p;
    while (x < 0) x += p;
    return x % p;
}


inline void work() {
    int L, R, Q;
    qword ans;
    while (m--) {
        cin >> L >> R >> Q;
        ans = Q;
        if (R - L >= Q) {cout << 0 << endl; continue;}
        rep(i,L,R) rep(j,i,R)
            ans = min(ans, mod(sum[j] - sum[i - 1],Q));
        cout << ans << endl;
    }
}

inline void solve() {
    int L, R, Q;
    qword ans;
    while (m--) {
        cin >> L >> R >> Q;
        ans = Q;
        if (R - L + 1 >= Q) {cout << 0 << endl; continue;}
        set<qword> s;
        s.insert(0);
        rep(i,L,R) {
            qword w = mod(sum[i] - sum[L - 1], Q);
            set<qword>::iterator it = s.upper_bound(w);
            if (it != s.begin()) --it;
            ans = min(ans, mod(w - *it, Q));
            s.insert(w);
        }
        cout << ans << endl;
    }
}

#define OK

int main() {
#ifdef OK
    freopen("seq.in","r",stdin);
    freopen("seq.out","w",stdout);
    ios::sync_with_stdio(0);
#endif // OK
    Init();
    if(n <= 100000 && m<=10000) work();
    else solve();
}

猜你喜欢

转载自www.cnblogs.com/Alessandro/p/9587822.html