Template

算法模板(乱序)

树状数组

template <typename T>
class fenwick {
 public:
  vector<T> fenw;
  int n;
 
  fenwick(int _n) : n(_n) {
    fenw.resize(n);
  }
 
  void modify(int x, T v) {
    while (x < n) {
      fenw[x] += v;
      x |= (x + 1);
    }
  }
 
  T get(int x) {
    T v{};
    while (x >= 0) {
      v += fenw[x];
      x = (x & (x + 1)) - 1;
    }
    return v;
  }

  T get(int l, int r) {
    return get(r) - get(l - 1);
  }

};

并查集 DSU

struct DSU {
  vector<int> f, siz, rank;
  int cnt; //统计还剩多少个连通块
  DSU(int n) : cnt(n), f(n), rank(n, 0), siz(n, 1) { iota(f.begin(), f.end(), 0); }
  int find(int x) {
    while (x != f[x]) x = f[x] = f[f[x]];
    return x;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int merge(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return -1;
    else -- cnt;
    if(rank[x] > rank[y]) swap(x, y);
    siz[y] += siz[x];
    f[x] = y;
    if(rank[x] == rank[y]) rank[y] ++;
    return y;
  }
  int size(int x) { return siz[find(x)]; }
}; //按秩合并 and 路径压缩 

dijkstra

template <typename T> //son[].second (int or ll)
vector<T> dijkstra(vector<vector<pair<int, int> > > &son, int n, int Start = 0) {
  struct node { int u; T d; bool operator < (const node &Tnode) const {
      return d > Tnode.d;
    }
  };
  priority_queue<node> q; 
  vector<int> st(n); vector<T> dist(n, INT_MAX); //最大值修改一下
  q.push({Start, 0}); dist[Start] = 0;
  while (not q.empty()) {
    auto [u, d] = q.top(); q.pop();
    if (st[u]) continue; st[u] = 1;
    for (auto &[v, w]: son[u]) {
      if (d + w < dist[v]) {
        dist[v] = d + w; 
        q.push({v, d + w});
      }
    }
  }
  return dist;
}

void solve() {
  int n, m; cin >> n >> m;
  vector<vector<pair<int, int> > > son(n);
  for (int i = 1, u, v, w; i <= m; i++ ) {
    cin >> u >> v >> w; u --, v --;
    son[u].push_back(make_pair(v, w)); 
  }
  auto dist = dijkstra<ll>(son, n);
  if (dist.back() > 1E9) dist.back() = -1;
  cout << dist.back();
}

快读

struct FastIO{//不可与scanf,printf,getchar,putchar,gets,puts,cin,cout混用
private:
	static const int BUFSIZE=1e5;
	char buf[BUFSIZE];int pos,len;//读入buffer(缓冲器)以及读入指针
	int wpos;char wbuf[BUFSIZE];//输出指针以及输出buffer
	#define gc() (pos==len&&(len=(pos=0)+fread(buf,1,BUFSIZE,stdin),!len)?EOF:buf[pos++])	
	#define pc(c) (wpos==BUFSIZE?fwrite(wbuf,1,BUFSIZE,stdout),wpos=0,wbuf[wpos++]=c:wbuf[wpos++]=c)
public:
	FastIO():wpos(0),pos(0),len(0){}
	~FastIO(){if(wpos)fwrite(wbuf,1,wpos,stdout),wpos=0;}	
	inline char getc(){return gc();}//读取char
	inline void putc(char c){pc(c);}//输出字符
	inline long long rd(){//读取long long
		long long x=0;char c=gc();bool f=0;
		for(;c<'0'||c>'9';c=gc())f|=c=='-';
		for(;c>='0'&&c<='9';c=gc())x=(x<<3)+(x<<1)+(c^48);
		return f?-x:x;
	}
	template<typename T>inline bool read(T &x){//多测读整数while(io.read(n))work();本地测试请输入两次ctrl Z 
		x=0;char c=gc();bool f=0;
		for(;c<'0'||c>'9';c=gc()){if(c==EOF)return false;f|=c=='-';}
		for(;c>='0'&&c<='9';c=gc())x=(x<<3)+(x<<1)+(c^48);
		if(f)x=-x;return true;
	}
	inline void wt(long long x){//输出整数
		if(x<0)pc('-'),x=-x;
		char a[20];short int h=0;
		for(a[++h]='0'+x%10,x/=10;x;x/=10)a[++h]='0'+x%10;
		for(;h;)pc(a[h--]);
	}
	inline void wtl(long long x){wt(x);pc('\n');}//write line输出整数并换行
	inline void wtb(long long x){wt(x);pc(' ');}//write blank输出整数并空格
	inline int gets(char s[]){int l=0;char c=gc();for(;c<=' ';c=gc());for(;c>' ';c=gc())s[l++]=c;s[l]=0;return l;}
	inline void puts(const char *s){for(const char *p=s;*p;)pc(*p++);}//输出字符串 (不带换行)
	template<typename T>inline FastIO & operator >> (T &a){return read(a),*this;}//io>>a>>b;只能输入整数
	inline FastIO & operator << (long long a){return wtb(a),*this;}//io<<a<<b;输出整数并带有空格
}io;

取模函数

const int MOD = 998244353;

inline int mod(int x) {return x >= MOD ? x - MOD : x;}

inline int ksm(int a, int b) {
  int ret = 1; a = mod(a);
  for(; b; b >>= 1, a = 1LL * a * a % MOD) if(b & 1) ret = 1LL * ret * a % MOD;
  return ret;
}

template<int MOD> 
struct modint {
  int x;
  modint() {x = 0; }
  modint(int y) {x = y;}
  inline modint inv() const { return modint{ksm(x, MOD - 2)}; }
  explicit inline operator int() { return x; }
  friend inline modint operator + (const modint &a, const modint& b) { return modint(mod(a.x + b.x)); }
  friend inline modint operator - (const modint &a, const modint& b) { return modint(mod(a.x - b.x + MOD)); }
  friend inline modint operator * (const modint &a, const modint& b) { return modint(1ll * a.x * b.x % MOD); }
  friend inline modint operator / (const modint &a, const modint& b) { return modint(1ll * a.x * b.inv().x % MOD); }
  friend inline modint operator - (const modint &a) { return modint(mod(MOD - a.x)); }
  friend inline modint& operator += (modint &a, const modint& b) { return a = a + b; }
  friend inline modint& operator -= (modint &a, const modint& b) { return a = a - b; }
  friend inline modint& operator *= (modint &a, const modint& b) { return a = a * b; }
  friend inline modint& operator /= (modint &a, const modint& b) { return a = a / b; }
  friend auto &operator >> (istream &i, modint &a) {return i >> a.x; }
  friend auto &operator << (ostream &o, const modint &z) { return o << z.x; }
  inline bool operator == (const modint &b) { return x == b.x; }
  inline bool operator != (const modint &b) { return x != b.x; }
  inline bool operator < (const modint &a) { return x < a.x; }
  inline bool operator <= (const modint &a) { return x <= a.x; }
  inline bool operator > (const modint &a) { return x > a.x; }
  inline bool operator >= (const modint &a) { return x >= a.x; }
  
};

typedef modint<MOD> mint;

inline mint ksm(mint a, int b) {
	mint ret = 1; 
	for(; b; b >>= 1, a = a * a ) if(b & 1) ret = ret * a ;
	return ret;
}

const int N = 2e5 + 10;

mint fact[N + 1], infact[N + 1], inv[N + 1];

void init() {
  fact[0] = 1; for(int i = 1; i <= N; ++ i ) { fact[i] = fact[i - 1] * i; }
  infact[N] = ksm(fact[N], MOD - 2); for(int i = N - 1; i >= 0; -- i ) infact[i] = infact[i + 1] * (i + 1);
  inv[0] = inv[1] = 1; for(int i = 2; i <= N; ++ i) inv[i] = inv[MOD % i] * (MOD - MOD / i);
}

封装线段树

int a[100010];
struct segment_tree {
    struct tree {int tl, tr, val, tag;} t[M << 2];
    #define l(x) t[(x)].tl
    #define r(x) t[(x)].tr
    #define len(x) (r(x) - l(x) + 1)
    #define val(x) t[(x)].val
    #define tag(x) t[(x)].tag
    #define lson k << 1
    #define rson k << 1 | 1
    void pushup(int k)
    {val(k)=val(lson)+val(rson);}
    void pushdown(int k) 
    {val(lson) += tag(k) * len(lson), val(rson) += tag(k)*len(rson); 
     tag(lson) += tag(k), tag(rson) += tag(k); tag(k) = 0;}
     void build(int k, int l, int r) {
         l(k) = l, r(k) = r;
         if(l == r) {val(k) = a[l]; return;}
         int Mid = (l + r) >> 1;
         build(lson,l,Mid);
         build(rson, Mid + 1, r); 
         pushup(k);
     } 
     void update(int k, int l, int r, int z) {
         if(l(k) >= l && r(k) <= r) {val(k) += z*len(k), tag(k) += z; return;}
         if(l(k) > r || r(k) < l)return;
         pushdown(k);
         update(lson, l, r, z); update(rson, l, r, z);
         pushup(k);
     }
     int query(int k, int l, int r) {
         if(l(k) >= l && r(k) <= r) return val(k);
         if(l(k) > r || r(k) < l) return 0;
         pushdown(k);
         return query(lson, l, r) + query(rson, l, r);
     }
     
}T; 

最大子段和 线段树

int w[N];
struct segment {
	struct node {int l, r; int lmax, rmax, tmax, sum; } tr[N << 2];
	#define lson (u << 1)
	#define rson (u << 1 | 1)
	#define Mid (l + r) / 2
	#define mid (tr[u].l + tr[u].r) / 2
	void pushup(node &u, node &l, node &r) {
		u.lmax = max(l.lmax, l.sum + r.lmax);
		u.rmax = max(r.rmax, r.sum + l.rmax);
		u.sum = l.sum + r.sum;
		u.tmax = max(max(l.tmax, r.tmax), l.rmax + r.lmax);
	}
	
	void pushup (int u) {
		pushup(tr[u], tr[lson], tr[rson]);
	}
		
	void build(int u, int l, int r) {
		if(l == r) {
			tr[u] = {l, r, w[l], w[l], w[l], w[l]};
		} else {
			tr[u] = {l, r};
			build(lson, l, Mid), build(rson, Mid + 1, r);
			pushup(u);
		}
	}
	
	void modify(int u, int idx, int val) {
		if(tr[u].l >= idx && tr[u].r <= idx) {
			tr[u] = {idx, idx, val, val, val, val};
		} else if(tr[u].l > idx || tr[u].r < idx) {
			return ;
		} else {
			modify(lson, idx, val);
			modify(rson, idx, val);
			pushup(u);
		}
	}
	
	node query(int u, int l, int r) {
		if(tr[u].l >= l && tr[u].r <= r) {
			return tr[u];
		} else if(r <= mid) {
			return query(lson, l, r);
		} else if(l > mid) {
			return query(rson, l, r);
		} else {
			node ans;
			node left = query(lson, l, r);
			node right = query(rson, l, r);
			pushup(ans, left, right);
			return ans;
		}
	}
	
}T;

手写 \(hash\) 函数

  1. 第一种
struct splitmix64 {
    size_t operator()(size_t x) const {
        static const size_t fixed = chrono::steady_clock::now().time_since_epoch().count();
        x += 0x9e3779b97f4a7c15 + fixed;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
};
unordered_map<int, int, splitmix64> mp;
  1. 第二种
struct Hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

trie 树

// by 绒绒 http://oj.daimayuan.top/submission/135434
struct Trie {
    int c[N][26], tot, v[N];
    void init() {
        while (tot) {
            v[tot] = 0;
            memset(c[tot], 0, sizeof(c[tot]));
            --tot;
        }
        memset(c[0], 0, sizeof(c[0]));
        v[0] = 0;
    }
    void insert(char s[], int len) {
        int now = 0;
        for (int i = 0; i < len; ++i) {
            int to = s[i] - 'a';
            if (!c[now][to])c[now][to] = ++tot;
            now = c[now][to];
        }
        v[now] = 1;
    }
    bool query(char s[], int len) {
        int now = 0;
        for (int i = len - 1; ~i; --i) {
            int to = s[i] - 'a';
            if (!c[now][to])return 0;
            now = c[now][to];
        }
        return v[now];
    }
}A;

01 trie

// by 严格鸽 https://www.zhihu.com/people/yan-ge-ge-32-1
void init()
{
    nxt[0][0] = nxt[0][1] = 0;
    cnt = 1;
}
void add(int n)
{
    int cur = 0;
    for (int i = MAXBIT; i >= 0; --i)
    {
        int bit = (n >> i) & 1;       
        if (!nxt[cur][bit]) {
            nxt[cnt][0] = nxt[cnt][1] = 0;
            nxt[cur][bit] = cnt++;
        }
        cur = nxt[cur][bit];
    }
    val[cur] = n;
}


debug

namespace debugger {
#ifdef DEBUG
    template <typename T>
    void __print_var(string_view name, const T & x) { std::cerr << name << " = " << x; }
    void __print_var(string_view name, const string & x) { std::cerr << name << " = \"" << x << "\""; }
    void __print_var(string_view name, const char & x) { std::cerr << name << " = \'" << x << "\'"; }
    template <typename T>
    void __print_var(string_view name, const vector<T>& x) {
        std::cerr << name << " = ";
        bool is_first = true;
        for (auto & ele : x) std::cerr << (is_first ? (is_first = false, "[") : ", ") << ele;
        std::cerr << "]";
    }
    template <typename T>
    void __print_var(string_view name, const set<T>& x) {
        std::cerr << name << " = ";
        bool is_first = true;
        for (auto & ele : x) std::cerr << (is_first ? (is_first = false, "{") : ", ") << ele;
        std::cerr << "}";
    }
    template <typename K, typename V>
    void __print_var(string_view name, const map<K, V>& x) {
        std::cerr << name << " = ";
        bool is_first = true;
        for (auto & [k, v] : x) std::cerr << (is_first ? (is_first = false, "{") : ", ") << "(" << k << ": " << v << ")";
        std::cerr << "}";
    }
    template <typename T>
    void __log(string_view name, const T & x) {
        __print_var(name, x); std::cerr << '\n';
    }
    template <typename T, typename... Ts>
    void __log(string_view name, const T & x, const Ts&... others) {
        size_t pos = name.find(',');
        __print_var(name.substr(0, pos), x); std::cerr << ", ";
        __log(name.substr(pos + 1), others...);
    }
 
#define LOG(args...)\
    { std::cerr << "line " << __LINE__ << ": " << __func__ << "(): ";\
    __log(#args, ##args); }
#else
#define LOG(...)
#endif
}
using namespace debugger;

矩阵(方阵)快速幂


struct mat {
  int n; vector<vector<long long> > a;
  mat() {};
  mat(int _n) : n(_n){ 
    a.resize(n + 1); a[0].resize(n + 1);
    for(int i = 1; i <= n; i ++ ) {
      a[i].resize(n + 1);
      a[i][i] = 1; 
    }
  };
};
 
mat operator * (mat T1, mat T2)  {
  mat ret(T1.n);
  for(int i = 1; i <= T1.n; i ++ ) {
    for(int j = 1; j <= T1.n; j ++ ) {
      ll &res = ret.a[i][j];
      res = 0;
      for(int k = 1; k <= T1.n; k ++ ) {
        res = (res + T1.a[i][k] * T2.a[k][j]) % p;
      }
    }
  }
  return ret;
}
 
mat ksm(mat x, ll k) {
  mat ret(x.n);
  while(k) {
    if(k & 1) ret = ret * x;
    k >>= 1;
    x = x * x; 
  }
  return ret;
}
 

字符串哈希

//https://www.acwing.com/problem/content/843/
#include <bits/stdc++.h>
using namespace std;

using ull = unsigned long long;
using Hash = pair<ull, ull>;

//如果卡常就将重载的 % mod.first  %mod.second 删了,但是自然溢出可能会被卡..

constexpr Hash mod = {1000000069, 1000000067};

Hash operator*(const Hash &a, const Hash &b) {
  return {a.first * b.first % mod.first, a.second * b.second % mod.second};
}

Hash operator+(const Hash &a, const Hash &b) {
  return {(a.first + b.first) % mod.first, (a.second + b.second) % mod.second};
}

Hash operator-(const Hash &a, const Hash &b) {
  return {(a.first - b.first + mod.first) %  mod.first, (a.second - b.second + mod.second) % mod.second};
}

Hash operator*(const Hash &a, const ull &b) {
  return {a.first * b % mod.first, a.second * b % mod.second};
}


int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
//   Hash base = {rng(), rng()};
  Hash base = {rng() % mod.first, rng() % mod.second};
  int n, m; cin >> n >> m;
  string s; cin >> s;
  vector<Hash> hash(n + 1);
  hash[0] = {1, 1};
  for (int i = 1; i <= n; i++) hash[i] = hash[i - 1] * base;
  vector<Hash> a(n + 1);
  a[0] = {1, 1};
  for(int i = 1; i <= n; i ++ ) {
    a[i] = a[i - 1] * base + hash[0] * s[i - 1];
  }
  auto get = [&] (int l, int r) {
    return a[r] - a[l - 1] * hash[r - l + 1];  
  };
  
  while(m -- ) {
    int l1, r1, l2, r2; cin >> l1 >> r1 >> l2 >> r2;
    if(get(l1, r1) == get(l2, r2))  cout << "Yes\n";
    else cout << "No\n";
  }
  return 0;
}

马拉车

// https://www.acwing.com/problem/content/description/141/
#include <bits/stdc++.h>
using namespace std;

constexpr int N = 2000010;

int n, m, Case;
char s[N], str[N];
int p[N];

int manacher() {
  int rt = 0, mid = 0;
  int res = 0;
  for(int i = 1; i <= m; i ++ ) {
    p[i] = i < rt ? min(p[2 * mid - i], rt - i) : 1;
    while(str[i + p[i]] == str[i - p[i]]) ++ p[i];
    if(i + p[i] > rt) {
      rt = i + p[i];
      mid = i;
    }
    res = max(res, p[i] - 1);
  }
  return res;
}

int main() {
  str[0] = '!', str[1] = '#';
  while(scanf("%s", s), s[0] != 'E') {
    n = strlen(s);
    for(int i = 0; i < n; i ++ ) {
      str[i * 2 + 2] = s[i];
      str[i * 2 + 3] = '#';
    }
    m = n * 2 + 1;
    str[m + 1] = '@';
    printf("Case %d: %d\n", ++ Case, manacher());
  }


  return 0;
}

int128

#include <bits/stdc++.h>
using namespace std;
inline __int128 read()
{
    __int128 x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

inline void write(__int128 x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}

int main()
{
    __int128 a = read();
    write(a);
    return 0;
}
posted @ 2022-03-16 10:27  ccz9729  阅读(265)  评论(0编辑  收藏  举报