C++ Utils

#include <cmath>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iostream>
#include <regex>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;

class SegPoint
{
  public:
    explicit SegPoint(int n = 0) { arr.assign(n + 1, 0); }
    void add(int l, int r, int addent)
    {
        for (int i = r + 1; i > 0; i -= lowbit(i)) {
            arr[i] += addent;
        }
        for (int i = l; i > 0; i -= lowbit(i)) {
            arr[i] -= addent;
        }
    }
    int at(int index)
    {
        int ret = 0;
        for (int i = index + 1; i < int(arr.size()); i += lowbit(i)) {
            ret += arr[i];
        }
        return ret;
    }

  private:
    int lowbit(int n) { return n & (-n); }
    vector<int> arr;
};

double comb(int n, int m)
{
    if (2 * m > n) {
        m = n - m;
    }
    if (m < 0) {
        return 0;
    } else if (m == 0) {
        return 1;
    } else {
        double ret = 1;
        for (int i = 1; i <= m; ++i) {
            ret = ret * (n - i + 1) / i;
        }
        return ret;
    }
}

int gcd(int m, int n)
{
    m = (m < 0) ? -m : m;
    n = (n < 0) ? -n : n;
    if (m < n) {
        swap(m, n);
    }
    while (n) {
        m = m % n;
        swap(m, n);
    }
    return m;
}

int gcd(int m, int n, pair<int, int> &coef)
{
    pair<int, int> vm(1, 0), vn(0, 1);
    if (m < 0) {
        m = -m;
        vm.first = -1;
    }
    if (n < 0) {
        n = -n;
        vn.second = -1;
    }
    if (m < n) {
        swap(m, n);
        swap(vm, vn);
    }
    while (n) {
        int k = m / n;
        m = m % n;
        vm.first -= k * vn.first;
        vm.second -= k * vn.second;
        swap(m, n);
        swap(vm, vn);
    }
    // cout << "vm: " << vm.first << " " << vm.second << endl;
    coef = vm;
    return m;
}

int jacobi(int m, int n, bool first = true)
{
    if (first) {
        // check validity
        if (n % 2 == 0 || n < 3) {
            cout << "n should be odd number bigger than 1
";
            return 0;
        } else if (gcd(m, n) != 1) {
            return 0;
        }
    }
    int c = 1;
    // mod n
    m = ((m % n) + n) % n;
    // divide all 2
    int j2 = (n % 8 == 1 || n % 8 == 7) ? 1 : -1;
    while (m % 2 == 0) {
        c *= j2;
        m /= 2;
    }
    if (m == 1) {
        return c;
    } else {
        if (m % 4 == 3 && n % 4 == 3) {
            c = -c;
        }
        return c * jacobi(n, m, false);
    }
}

vector<int> sieve(int MaxP, int MaxN = 0)
{
    vector<int> ret;
    vector<bool> notPrime(MaxP + 1, false);
    for (int i = 2; i <= MaxP; ++i) {
        if (!notPrime[i]) {
            ret.push_back(i);
        }
        for (int j = 0; j < (int)ret.size() && ret[j] * i <= MaxP; ++j) {
            notPrime[ret[j] * i] = true;
            if (i % ret[j] == 0) {
                break;
            }
        }
    }
    if (MaxN > 0) {
        ret.resize(MaxN);
    }
    return ret;
}

int power(int n, int e, const int mod = 0)
{
    pair<int, int> coef;
    // check validity
    if (mod < 0) {
        cout << "mod should be nonegative
";
        return 0;
    }
    if (mod == 0 && e < 0) {
        cout << "negative power of integer is forbidden, try pow() instead
";
        return 0;
    }
    if (mod && e < 0) {
        n = ((n % mod) + mod) % mod;
        pair<int, int> coef;
        if (gcd(n, mod, coef) != 1) {
            cout << "the inverse of n does not exist as n is not coprime to "
                    "mod
";
            return 0;
        } else {
            n = ((coef.first % mod) + mod) % mod;
            e = -e;
        }
    }

    long long ret = 1, lmod = mod, tmp = n;
    for (int i = 1; i <= e; i <<= 1) {
        if (i & e) {
            ret = mod ? ret * tmp % lmod : ret * tmp;
        }
        tmp = mod ? tmp * tmp % lmod : tmp * tmp;
    }
    return int(ret);
}

double gpa(int score)
{
    if (score >= 90) {
        return 4;
    } else if (score >= 87) {
        return 3.9;
    } else if (score >= 85) {
        return 3.8;
    } else if (score >= 83) {
        return 3.7;
    } else if (score >= 82) {
        return 3.6;
    } else if (score >= 80) {
        return 3.5;
    } else if (score >= 78) {
        return 3.4;
    } else if (score >= 76) {
        return 3.3;
    } else if (score >= 75) {
        return 3.2;
    } else if (score >= 74) {
        return 3.1;
    } else if (score >= 73) {
        return 3.0;
    } else if (score >= 72) {
        return 2.9;
    } else if (score >= 71) {
        return 2.8;
    } else if (score >= 69) {
        return 2.7;
    }
    return -1e18;
}

void calcGpa()
{
    ifstream fin;
    fin.open("gpa.txt");
    double credits = 0, sum = 0, c;
    int s, cnt = 0;
    while (fin >> c >> s) {
        cnt++;
        credits += c;
        sum += c * gpa(s);
    }
    fin.close();
    cout << cnt << " lessons
"
         << credits << " credits
"
         << "GPA = " << sum / credits << endl;
}

bool verify(char v = 'y')
{
    string ansStr;
    char ans;
    cin >> ansStr;
    ans = ansStr[0];
    if (tolower(ans) == tolower(v)) {
        return true;
    }
}

void split(const string &s, vector<string> &tokens, const char &delim = ' ')
{
    tokens.clear();
    size_t lastPos = s.find_first_not_of(delim, 0);
    size_t pos = s.find(delim, lastPos);
    while (lastPos != string::npos) {
        tokens.emplace_back(s.substr(lastPos, pos - lastPos));
        lastPos = s.find_first_not_of(delim, pos);
        pos = s.find(delim, lastPos);
    }
}

void trim(string &str)
{
    string blanks(" fv
	
 ");
    str.erase(0, str.find_first_not_of(blanks));
    str.erase(str.find_last_not_of(blanks) + 1);
}

bool bookify(const string &filename)
{
    cout << "The following file is to be bookified:
	" << filename
         << "
Make sure it is encoded in UTF-8 (y/n): ";
    if (!verify()) {
        return false;
    }

    string tmp;
    cout << "Chapter regular expression (第.{1,20}章):
	";
    cin >> tmp;
    regex chaReg('^' + tmp);

    vector<string> commas;
    cout << "Each line must end with specific commas (。!?”」…*.!?):
	";
    cin >> tmp;
    regex endReg('[' + tmp + "]$");

    int nSpaces;
    cout << "Each line must begin with some number of spaces: ";
    cin >> nSpaces;

    string outFile = filename;
    outFile.insert(filename.find_last_of("."), "_out");
    cout << "Output file would be:
	" << outFile
         << "
Confirm or type a new one (c/t): ";
    if (!verify('c')) {
        cout << "Type a new one:
	";
        cin >> outFile;
    }

    ifstream fin;
    fin.open(filename.c_str());
    if (!fin.is_open()) {
        cout << "Fail to open file
";
        return false;
    }
    ofstream fout;
    fout.open(outFile.c_str());

    int chapCnt = 0;
    bool isStart = true;
    while (fin.good()) {
        getline(fin, tmp);
        trim(tmp);
        if (regex_search(tmp, chaReg)) {
            tmp = regex_replace(tmp, chaReg, "");
            trim(tmp);
            if (chapCnt) {
                fout << endl << endl;
            }
            fout << "第" << ++chapCnt << "章 " << tmp << endl << endl;
            cout << "第" << chapCnt << "章 " << tmp << endl;
            isStart = true;
        } else {
            if (isStart) {
                for (int i = 0; i < nSpaces; ++i) {
                    fout << " ";
                }
            }
            if (regex_search(tmp, endReg)) {
                fout << tmp << endl;
                isStart = true;
            } else {
                fout << tmp;
                isStart = false;
            }
        }
    }

    fin.close();
    fout.flush();
    fout.close();
    return true;
}

bool prepareForEpub(const string &filename)
{
    cout << "The following file is to be bookified:
	" << filename
         << "
Make sure it is encoded in UTF-8 (y/n): ";
    if (!verify()) {
        return false;
    }

    ifstream conf;
    conf.open("epub.conf");
    if (!conf.is_open()) {
        cout << "Fail to open configure file
";
        return false;
    }

    string tmp;
    conf >> tmp;
    regex volReg(tmp);
    conf >> tmp;
    regex chaReg(tmp);
    conf >> tmp;
    regex endReg(tmp);
    int nSpaces;
    conf >> nSpaces;
    conf.close();

    ifstream fin;
    fin.open(filename.c_str());
    if (!fin.is_open()) {
        cout << "Fail to open file
";
        return false;
    }

    string outFile = filename;
    outFile.insert(filename.find_last_of("."), "_out");
    cout << "Output file would be:
	" << outFile << endl;
    ofstream fout;
    fout.open(outFile.c_str());

    bool isStart = true;
    while (fin.good()) {
        getline(fin, tmp);
        trim(tmp);
        if (regex_search(tmp, volReg)) {
            fout << "# " << tmp << endl << endl;
            isStart = true;
        } else if (regex_search(tmp, chaReg)) {
            fout << "## " << tmp << endl << endl;
            isStart = true;
        } else {
            if (isStart) {
                for (int i = 0; i < nSpaces; ++i) {
                    fout << " ";
                }
            }
            if (regex_search(tmp, endReg)) {
                fout << tmp << endl << endl;
                isStart = true;
            } else {
                fout << tmp;
                isStart = false;
            }
        }
    }

    fin.close();
    fout.flush();
    fout.close();
    return true;
}

int w(int n)
{
    int ret = 0;
    for (int m = 1; m <= n; m <<= 1) {
        if (m & n) {
            ret++;
        }
    }
    return ret;
}

int stirling1(int p, int k) {
    if (p < k || k < 0) {
        cout << "p >= k >= 0
";
        return 0;
    } else if (k == p) {
        return 1;
    } else if (k == 0) {
        return 0;
    } else {
        return stirling1(p-1,k-1) + (p-1)*stirling1(p-1,k);
    }
}

int stirling2(int p, int k) {
    if (p < k || k < 0) {
        cout << "p >= k >= 0
";
        return 0;
    } else if (k == p) {
        return 1;
    } else if (k == 0) {
        return 0;
    } else {
        return stirling2(p-1,k-1) + k*stirling2(p-1,k);
    }
}

class Permutation
{
public:
    Permutation() {}
    bool input() {
        data.clear();

        int n;
        cin >> n;
        if (n <= 1) {
            return false;
        } else {
            vector<bool> flag(n, false);
            for (int i = 0, t; i < n; ++i) {
                cin >> t;
                if (t < 1 || t > n || flag[t-1]) {
                    data.clear();
                    return false;
                } else {
                    flag[t-1] = true;
                    data.emplace_back(t-1);
                }
            }
            return true;
        }
    }
    int length() const {
        return data.size();
    }
    Permutation operator* (const Permutation& sig) const {
        if (length() != sig.length()) {
            cout << "Illegal to multiple two permutation of different order
";
            return Permutation();
        }
        Permutation ret = sig;
        for (int i = 0; i < length(); ++i) {
            ret[i] = data[sig[i]];
        }
        return ret;
    }
    bool operator== (const Permutation& sig) const {
        if (length() != sig.length()) {
            return false;
        } else {
            for (int i = 0; i < length(); ++i) {
                if (data[i] != sig[i]) {
                    return false;
                }
            }
            return true;
        }
    }
    void print() {
        int n = length();
        vector<bool> flag(n, false);
        for (int i = 0; i < n; ++i) {
            if (!flag[i]) {
                cout << "(" << i+1;
                int t = data[i];
                while (t != i) {
                    flag[t] = true;
                    cout << " " << t+1;
                    t = data[t];
                }
                cout << ")";
            }
        }
        cout << endl;
    }
protected:
    const int& operator[] (int index) const {
        return data.at(index);
    }
    int& operator[] (int index) {
        return data[index];
    }
private:
    vector<int> data; // 0 indexed
};

class Group
{
public:
    void clear() {
        data.clear();
    }
    void addElement(const Permutation& sig) {
        data.emplace_back(sig);
    }
    void inputGenerator() {
        data.clear();
        while (1) {
            Permutation sig;
            if (!sig.input()) {
                return;
            } else {
                data.emplace_back(sig);
            }
        }
    }
    void setIterNumber(int n) {
        nIter = n;
    }
    void startIter() {
        for (int i = 0; i < nIter; ++i) {
            int n = data.size();
            Permutation sig = data[rand()%n] * data[rand()%n];
            bool found = false;
            for (auto& tau: data) {
                if (tau == sig) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                data.emplace_back(sig);
            }
        }
    }
    void print() {
        for (auto& sig: data) {
            sig.print();
        }
    }
private:
    vector<Permutation> data;
    int nIter;
};

int main() {
    srand((unsigned)time(NULL));

    Group d;
    d.setIterNumber(100);
    d.inputGenerator();
    d.startIter();
    d.print();
}
原文地址:https://www.cnblogs.com/maoruimas/p/13190358.html