2018-常州集训提高组-测试二


测之前发一波解题报告,奶一口自己。

总的来说,这套题大概也就普及+/提高-难度吧,可以说是T1合集。

总结

  1. 第一题想复杂了,浪费了十分钟。
  2. 最后一道题,方差忘了怎么搞的,最后还是看答案推出来的

B君的任务

题目分析

贪心,和字符串加法那道题很像。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <ctime>
#include <cmath>
using namespace std;
typedef long long qword;
#define rep(i,s,t) for(int i=(int)(s);i<=(int)(t);++i)
#define forn(i,n) for(int i=1;i<=(int)(n);++i)
#define pb push_back
#define seta(h, x) memset(h, x, sizeof(h))
#define fr first
#define sc second

const int maxn = 100010;
qword a[maxn], b[maxn];
int r[maxn];
bool cmp(const int &x, const int &y) {
    return b[x] * a[y] < a[x] * b[y];
}

const string task = "task";

int main() {
    freopen((task + ".in").data(),"r",stdin);
#ifndef Debug
    freopen((task + ".out").data(),"w",stdout);
#endif // Debug
    int n;
    cin >> n;

    int temp = 0;
    forn(i, n) {
        cin >> a[i] >> b[i];
        if (a[i] == 0 && b[i] == 0) {i --; n --; continue;}
        r[i] = i;
    }
    sort(r + 1, r + 1 + n, cmp);
    qword Tot = 0;
    qword ans = 0;
    forn(i, n) {
        int oo = r[i];
        Tot += b[oo];
        ans += Tot * a[oo];
    }
    cout << ans << endl;
}

B 君的病症

题目分析

组合数学,乘法逆元

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <ctime>
#include <cmath>
using namespace std;
typedef long long qword;
#define rep(i,s,t) for(int i=(int)(s);i<=(int)(t);++i)
#define forn(i,n) for(int i=1;i<=(int)(n);++i)
#define pb push_back
#define seta(h, x) memset(h, x, sizeof(h))
#define fr first
#define sc second

const int maxn = 155010;
const string task = "ocd";
int a[maxn];
qword sum[maxn];
qword f[maxn];
const int p = 1000000007;

qword qpow(qword a, qword b) {qword ans=1;for(;b;b>>=1,a=a*a%p) {if(b&1) ans=ans*a%p;} return ans;}

qword C(qword n, qword m) {return f[n] * qpow((f[n - m]), p - 2) % p * qpow(f[m], p - 2) % p;}


int main() {
    freopen((task + ".in").data(),"r",stdin);
#ifndef Debug
    freopen((task + ".out").data(),"w",stdout);
#endif // Debug
    int n;
    cin >> n;
    forn(i, n) {cin >> a[i]; sum[i] = sum[i - 1] + a[i];}
    f[0] = 1;
    forn(i, sum[n]) {f[i] = f[i - 1] * i % p;}
    qword ans = 1;
    rep(i,2,n) {
        ans = ans * C(sum[i] - 2, a[i] - 2) % p;
    }
    cout << ans << endl;
}

B 君的方案

题目分析

维护(x), (x^2)两个单点修改,区间查询。裸的数据结构。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <ctime>
#include <cmath>
using namespace std;
typedef long long qword;
#define rep(i,s,t) for(int i=(int)(s);i<=(int)(t);++i)
#define forn(i,n) for(int i=1;i<=(int)(n);++i)
#define pb push_back
#define seta(h, x) memset(h, x, sizeof(h))
#define fr first
#define sc second

const int maxn = 200010;
const string task = "variance";

qword C[2][maxn];
qword a[maxn];
int n;

void Add(int opt, int x, int v) {for(;x<=2*n;x+=x&-x) C[opt][x]+=v;}
qword Query(int opt, int x) {qword res=0;for(;x;x-=x&-x) res+=C[opt][x];return res;}

int main() {
    freopen((task + ".in").data(),"r",stdin);
#ifndef Debug
    freopen((task + ".out").data(),"w",stdout);
#endif // Debug
    int m;
    cin >> n >> m;
    forn(i, n) {
        cin >> a[i];
        Add(0, i, a[i]);
        Add(1, i, a[i] * a[i]);
    }
    qword ave = 0;
    qword ans = 0;
    qword all = 0;
    int opt, x, y;
    forn(i, m) {
        cin >> opt >> x >> y;
        if (opt == 1) {
            Add(0, x, y - a[x]);
            Add(1, x, y * y - a[x] * a[x]);
            a[x] = y;
        } else {
            all = Query(0, y) - Query(0, x-1);
            ans = Query(1, y) - Query(1, x-1);
            ans = 1ll * (y-x+1) * ans - all * all;
            cout << ans << endl;
        }
    }
}

原文地址:https://www.cnblogs.com/Alessandro/p/9592924.html