zoukankan      html  css  js  c++  java
  • CSP 2019 模板整合

    qwq以下都为9.24后写的模板

    namespace IO{
    	const int S = 1 << 20;
    	char I[S + 1], *Is = I, *It = I, O[S + 1], *Ot = O;
    	char gc() {return Is == It ? ((It = (Is = I) + fread(I, 1, S, stdin)) == I ? EOF: *Is++): *Is++;}
    	void flush() {fwrite(O, 1, Ot - O, stdout), Ot = O;}
    	void pc(char ch) {Ot == O + S? flush(), *Ot++ =ch: *Ot++ = ch;}
    	struct flusher{ ~flusher(){flush();}}Flusher;
    	#define getchar gc
    	#define putchar pc
    	inline int read() {
    		int x = 0; char v = gc();
    		for (; v < 48 || v > 57; v = gc());
    		for (; v >= 48 && v <= 57; v = gc()) x = (x << 3) + (x << 1) + (v ^ 48);
    		return x;
    	}
    	inline void write(int x) {
    		static int buf[100], d;
    		if (x == 0) pc('0');
    		else {
    			for (d = 0; x; x /= 10) buf[++d] = x % 10 + 48;
    			while (d) pc((char)buf[d--]);
            }
    	}
    }
    using namespace IO;
    

    快读

    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    

    GCD

    int GCD(int x, int y) {
    	return y ? GCD(y, x % y) : x;
    }
    

    快速幂

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

    扩欧

    void exgcd(int a, int b) {
        if (b == 0) {
            x = 1, y = 0;
            return;
        }
        exgcd(b, a % b);
        int k = x;
        x = y, y = k - a / b * y;
    }
    
    int exgcd(int a, int b, int &x, int &y) {
        if (!b) {
            x = 1, y = 0;
            return a;
        }
        int d = exgcd(b, a % b, y, x);
        y -= a / b * x;
        return d;
    }
    
    struct Matrix {
        int n, a[N][N];
    
        Matrix(int _n = 0) {
            n = _n;
            memset(a, 0, sizeof(a));
        } 
    
        void operator ~(){
            for (int i = 0; i < n; i++)
                a[i][i] = 1;
        }
    
        Matrix operator *(const Matrix &b) const {
            Matrix sum(n);
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    for (int k = 0; k < n; k++)
                        sum.a[i][k] = (sum.a[i][k] + 1LL * a[i][j] * b.a[j][k] % Mo) % Mo;
            return sum;
        }
        
        Matrix operator^(long long p) const {
            Matrix sum(n), x = *this;
            ~sum;
            for (; p; p >>= 1, x = x * x)
                if (p & 1) sum = sum * x;
            return sum;
        }
    } ;
    

    CDQ

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 2e6 + 10;
    
    int n, k, b[N], tot, f[N];
    
    struct Node {
        int x, y, z, cnt, ans, id;
    } a[N], c[N];
    
    inline int read() {
        int x = 0, k = 1; char ch = getchar();
        for (; ch < 48 || ch > 57; ch = getchar()) k ^= (ch == '-');
        for (; ch >= 48 && ch <= 57; ch = getchar()) x = x * 10 + (ch ^ 48);
        return k ? x : -x;
    }
    
    inline bool cmp (Node x, Node y) {
        return x.x == y.x ? x.y == y.y ? x.z < y.z : x.y < y.y : x.x < y.x;
    }
    
    inline bool pd_equal(Node x, Node y) {
        return x.x != y.x || x.y != y.y || x.z != y.z;
    }
    
    inline void add(int x, int val) {
        for (; x <= k; x += (x & (-x)))
            b[x] += val;
    }
    
    inline int query(int x) {
        int ans = 0;
        for (; x; x -= (x & (-x)))
            ans += b[x];
        return ans;
    }
    
    void CDQ(int l, int r) {
        if (l == r)
            return;
        int mid = l + r >> 1;
        CDQ(l, mid), CDQ(mid + 1, r);
        for (int i = l, j = mid + 1, k = l; i <= mid || j <= r; k++) 
            if (j > r || (i <= mid && a[i].y <= a[j].y))
                c[k] = a[i++];
            else 
                c[k] = a[j++];
        for (int i = l; i <= r; i++)
            a[i] = c[i];
        for (int i = l; i <= r; i++)
            if (a[i].id <= mid)
                add(a[i].z, a[i].cnt);
            else 
                a[i].ans += query(a[i].z);
        for (int i = l; i <= r; i++)
            if (a[i].id <= mid)
                add(a[i].z, -a[i].cnt);
    }
    
    int main() {
        n = read(), k = read();
        for (int i = 1; i <= n; i++)
            a[i].x = read(), a[i].y = read(), a[i].z = read();
        std::sort(a + 1, a + 1 + n, cmp);
        for (int i = 1; i <= n; i++)
            if (!tot || pd_equal(a[i], a[i - 1]))  
                a[++tot] = a[i], a[tot].id = tot, a[tot].cnt = 1;
            else 
                a[tot].cnt++;
        CDQ(1, tot);
        for (int i = 1; i <= tot; i++)
            f[a[i].ans + a[i].cnt - 1] += a[i].cnt;
        for (int i = 0; i < n; i++)
            printf("%d
    ", f[i]);
        return 0;
    }
    

    回文自动机(PAM) (9.24)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 5e5 + 10;
    char s[N];
    int Len;
    struct PAM{
    	int last, cnt, len[N], fail[N], num[N], k, p, ch[N][26], p1, c[N];
    	//char s[N];
    	void init(char *s) {
    		last = 0, cnt = 1, len[0] = 0, len[1] = -1, fail[0] = 1, fail[1] = 0, s[0] = 26;
    	}
    	void insert() {
    		for (int i = 1; i <= Len; i++) {
    			s[i] = (s[i] - 97 + k) % 26 + 97;
    			c[i] = s[i] - 'a';
    			p = last;
    			while (s[i - len[p] - 1] != s[i])
    				p = fail[p];
    			if (!ch[p][s[i]]) {
    				len[++cnt] = len[p] + 2, p1 = fail[p];
    				while (s[i - len[p1] - 1] != s[i])
    					p1 = fail[p1];
    				fail[cnt] = ch[p1][s[i]];
    				num[cnt] = num[fail[cnt]] + 1;
    				ch[p][s[i]] = cnt;
    			}
    			last = ch[p][s[i]];
    			printf("%d%c", num[last], (i == Len) ? '
    ' : ' ');
    			k = num[last];
    			}
    	}
    } s1;
    int main() {
    	scanf("%s", s + 1);
    	Len = strlen(s + 1);
    	s1.init(s);
    	s1.insert();
    	return 0;
    }
    

    AC自动机 (9.25)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 10, M = 160;
    int n;
    char s[M][N];
    int trie[N][26], tot, endword[N], fail[N];
    struct Node {
    	int num, pos;
    } Ans[N];
    inline void Init(int x) {
    	memset(trie[x], 0, sizeof(trie[x]));
    	fail[x] = endword[x] = 0;
    }
    inline void Build_Trie(int gg) {
    	int root = 0, len = strlen(s[gg] + 1);
    	for (int j = 1; j <= len; j++) {
    		if (!trie[root][s[gg][j] - 'a'])
    			trie[root][s[gg][j] - 'a'] = ++tot, Init(tot);
    		root = trie[root][s[gg][j] - 'a'];
    	}
    	endword[root] = gg;
    }
    inline void Get_Fail() {
    	queue <int> q;
    	for (int i = 0; i < 26; i++)
    		if (trie[0][i]) {
    			q.push(trie[0][i]);
    			fail[trie[0][i]] = 0;
    		}
    	while (!q.empty()) {
    		int now = q.front();
    		q.pop();
    		for (int i = 0; i < 26; i++)
    			if (trie[now][i]) {
    				fail[trie[now][i]] = trie[fail[now]][i];
    				q.push(trie[now][i]);
    			}
    			else {
    				trie[now][i] = trie[fail[now]][i];
    			}
    	}
    }
    inline int query() {
    	int len = strlen(s[n + 1] + 1), ans = 0, now = 0;
    	for (int i = 1; i <= len; i++) {
    		now = trie[now][s[n + 1][i] - 'a'];
    		for (int j = now; j; j = fail[j])
    			Ans[endword[j]].num++;
    	}
    	return ans;
    }
    inline bool cmp(Node x, Node y) {
    	return x.num > y.num || (x.num == y.num && x.pos < y.pos);
    }
    int main() {
    	scanf("%d", &n);
    	while (n != 0) {
    		tot = 0;
    		Init(0);
    		for (int i = 1; i <= n; i++) {
    			scanf("%s", s[i] + 1);
    			Ans[i].num = 0, Ans[i].pos = i;
    			Build_Trie(i);
    		}
    		fail[0] = 0;
    		Get_Fail();
    		scanf("%s", s[n + 1] + 1);
    		query();
    		std::sort(Ans + 1, Ans + 1 + n, cmp);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    		printf("%d
    %s
    ", Ans[1].num, s[Ans[1].pos] + 1);
    		for (int i = 2; i <= n; i++)
    			if (Ans[1].num == Ans[i].num)
    				printf("%s
    ", s[Ans[i].pos] + 1);
    			else 
    				break;
    		scanf("%d", &n);
    	}
    	return 0;
    }
    

    ‘’

    可持久化线段树(主席树) (9.25)

    题目

    (静态区间第k小)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10;
    int l[N << 5], r[N << 5], cnt, sum[N << 5], a[N], b[N], c[N], n, q, m; 
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    inline int Build(int t, int w) {
    	int now = ++cnt, mid = (t + w) >> 1;
    	sum[now] = 0;
    	if (t < w) {
    		l[now] = Build(t, mid);
    		r[now] = Build(mid + 1, w);
    	}
    	return now;
    }
    inline int add(int k, int t, int w, int x) {
    	int now = ++cnt, mid = (t + w) >> 1;
    	l[now] = l[k], r[now] = r[k], sum[now] = sum[k] + 1;
    	if (t < w && x <= mid)
    		l[now] = add(l[k], t, mid, x);
    	else if (t < w && x > mid)
    		r[now] = add(r[k], mid + 1, w, x);
    	return now;
    }
    inline int ask(int L, int R, int t, int w, int x) {
    	if (t >= w)
    		return t;
    	int mid = (t + w) >> 1, k = sum[l[R]] - sum[l[L]];
    	if (k >= x)
    		return ask(l[L], l[R], t, mid, x);
    	else 
    		return ask(r[L], r[R], mid + 1, w, x - k);
    }
    int main() {
    	n = read(), q = read();
    	for (int i = 1; i <= n; i++)
    		b[i] = a[i] = read();
    	std::sort(b + 1, b + 1 + n);
    	m = unique(b + 1, b + 1 + n) - b - 1;
    	c[0] = Build(1, m);
    	for (int i = 1; i <= n; i++) {
    		int now = lower_bound(b + 1, b  + 1 + m, a[i]) - b;
    		c[i] = add(c[i - 1], 1, m, now);
    	}
    	for (int i = 1; i <= q; i++) {
    		int x = read(), y = read(), z = read();
    		printf("%d
    ", b[ask(c[x - 1], c[y], 1, m, z)]);
    	}
    	return 0;
    }
    

    Manacher (9.25)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 31000000;
    int len, hw[N], ans;
    char s[N];
    inline void Manacher() {
        int maxright = 0, mid = 0;
        for (int i = 1; i < len; i++) {
            if (i < maxright)
                hw[i] = std::min(hw[(mid << 1) - i], hw[mid] + mid - i);
            else 
                hw[i] = 1;
            while (s[i + hw[i]] == s[i - hw[i]])
                ++hw[i];
            if (hw[i] + i > maxright)
                maxright = hw[i] + i, mid = i;
        }
    }
    int main() {
        scanf("%s", s + 1);
        len = strlen(s + 1);
        for (int i = len; i >= 1; i--)
            s[i * 2] = s[i];
        s[0] = s[1] = '#';
        for (int i = 1; i <= len; i++)
            s[i * 2 + 1] = '#';
        s[len * 2 + 2] = 0;
        len = len * 2 + 2;
        Manacher();
        ans = 1;
        for (int i = 0; i < len; i++)
            ans = std::max(ans, hw[i]);
        printf("%d
    ", ans - 1);
        return 0;
    }
    

    线性基 (9.26)

    插入、判断、查询最大最小值、查询第(k)小值

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 110;
    const int M = 50;
    int n;
    long long x, a[N + 10], b[N +10], ANS;
    bool flag;
    inline int read() {
        int x = 0, k = 1; char c = getchar();
        for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
        for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
        return k ? x : -x;
    }   
    inline long long read1() {
        long long x = 0, k = 1; char c = getchar();
        for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
        for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
        return k ? x : -x;
    }
    inline void Insert(long long x) {  //插入
        for (int i = M; i >= 0; i--)
            if (x & (1ll << i))
                if (!a[i]) {
                    a[i] = x;
                    return;
                }
                else x ^= a[i];
        flag = true;
    }
    inline bool check(long long x) {  //判断
        for (int i = M; i >= 0; i--) 
            if (x & (1ll << i)) {
                if (!a[i])
                    return false;
                else 
                    x ^= a[i];
            }
        return true;
    }
    inline long long Ask_max() {      //查询最大值
        long long maxx = 0;
        for (int i = M; i >= 0; i--)
            maxx = std::max(maxx, maxx ^ a[i]);
        return maxx;
    }
    inline long long Ask_min() {      //查询最小值
        if (flag)
            return 0;
        for (int i = 0; i <= M; i++)
            if (a[i])
                return a[i];
    }
    inline long long Ask_kth(long long x) {      //查询第k小值
        long long ans = 0;
        int cnt = 0;
        x -= flag;
        if (!x)
            return 0;
        for (int i = 0; i <= M; i++) {
            for (int j = i - 1; j >= 0; j--) 
                if (a[i] & (1ll << j))
                    a[i] ^= a[j];
            if (a[i])
                b[cnt++] = a[i];
        }
        if (x >= (1ll << cnt))
            return -1;
        for (int i = 0; i < cnt; i++)
            if (x & (1ll << i))
                ans ^= b[i];
        return ans;
    }
    signed main() {
        n = read();
        for (int i = 1; i <= n; i++) 
            a[i] = read1();
        std::sort(a + 1, a + 1 + n);
        for (int i = 1; i <= n; i++) 
            if (check(a[i]))
                ANS += a[i];
            else 
                Insert(a[i]);
        printf("%lld
    ", ANS);
        return 0;
    }
    

    高斯消元 (9.26)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 110;
    int n;
    double a[N][N];
    inline bool Gauss(int n, int m) {
        for (int i = 1; i <= n; i++) {
            int maxx = i;
            for (int j = i + 1; j <= n; j++)
                if (fabs(a[j][i]) > fabs(a[maxx][i]))
                    maxx = j;
            for (int j = 1; j <= m; j++)
                std::swap(a[i][j], a[maxx][j]);
            if (!a[i][i])
                return false;
            for (int j = 1; j <= n; j++)
                if (j != i) {
                    double t = a[j][i] / a[i][i];
                    for (int k = i + 1; k <= m; k++)
                        a[j][k] = a[j][k] - a[i][k] * t;
                }
        }
        return true;
    }
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n + 1; j++)
                scanf("%lf", &a[i][j]);
        if (!Gauss(n, n + 1))
            return printf("No Solution
    "), 0;
        for (int i = 1; i <= n; i++)
            printf("%.2f
    ", a[i][n + 1] / a[i][i]);
        return 0;
    }
    

    矩阵求逆 (9.26)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1010, Mo = 1e9 + 7;
    int n, a[N][N];
    inline int ksm(int a, int b) {
        int ans = 1;
        for (; b; b >>= 1, a = 1LL * a * a % Mo)
            if (b & 1) ans = 1LL * ans * a % Mo;
        return ans;
    }
    inline bool Gauss(int n, int m) {
    	for (int i = 1; i <= n; i++) {
    		int maxx = i;
    		for (int j = i + 1; j <= n; j++)
    			if (fabs(a[j][i]) > fabs(a[maxx][i]))
    				maxx = j;
    		if (i != maxx)		
    			for (int j = 1; j <= m; j++)
    				std::swap(a[i][j], a[maxx][j]);
    		if (!a[i][i])
    			return false;
    		int d = ksm(a[i][i], Mo - 2);
    		for (int j = i; j <= m; j++)
    			a[i][j] = 1LL * a[i][j] * d % Mo;
    		for (int j = 1; j <= n; j++)
    			if (j != i) {
    				d = a[j][i];
    				for (int k = i; k <= m; k++)
    					a[j][k] = (a[j][k] - 1LL * a[i][k] * d % Mo + Mo) % Mo;
    			}
    	}
    	return true;
    }
    signed main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++) {
    		for (int j = 1; j <= n; j++)
    			scanf("%d", &a[i][j]);
    		a[i][n + i] = 1;
    	}
    	if (!Gauss(n, n + n))
    		return printf("No Solution
    "), 0;
    	for (int i = 1; i <= n; i++)
    		for (int j = n + 1; j <= n + n; j++)
    			printf("%d%c", a[i][j], " 
    "[j == n + n]);
    	return 0;
    }
    

    普通莫队 (9.27)

    SP3267 DQUERY - D-query

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 3e4 + 10, M = 2e6 + 10;
    int n, m, now, be[M], a[M], cnt[M], ans[M];
    struct Node {
    	int l, r, id;
    } q[M];
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    inline bool cmp(Node a, Node b) {
    	return (be[a.l] ^ be[b.l]) ? be[a.l] < be[b.l] : ((be[a.l] & 1) ? a.r < b.r : a.r > b.r);
    } 
    int main() {
    	n = read();
    	int sz = sqrt(n), n1 = ceil((double)n / sz);
    	for (int i = 1; i <= n1; i++)
    		for (int j = (i - 1) * sz + 1; j <= i * sz; j++)
    			be[j] = i;
    	for (int i = 1; i <= n; i++)
    		a[i] = read();
    	m = read();
    	for (int i = 1; i <= m; i++)
    		q[i].l = read(), q[i].r = read(), q[i].id = i;
    	std::sort(q + 1, q + 1 + m, cmp);
    	int L = 1, R = 0;
    	for (int i = 1; i <= m; i++) {
    		int l = q[i].l, r = q[i].r;
    		while (L < l)
    			now -= !--cnt[a[L++]];
    		while (L > l)
    			now += !cnt[a[--L]]++;
    		while (R < r)
    			now += !cnt[a[++R]]++;
    		while (R > r)
    			now -= !--cnt[a[R--]];
    		ans[q[i].id] = now;
    	}
    	for (int i = 1; i <= m; i++)
    		printf("%d
    ", ans[i]);
    	return 0;
    }
    

    带修莫队 (9.27)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 3e4 + 10, M = 2e6 + 10;
    int n, m, now, be[M], a[M], cnt[M], ans[M], cntc, cntq;
    char ch;
    struct Query {
    	int l, r, id, time;
    } q[M];
    struct Replace {
    	int pos, color;
    } c[M];
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    inline bool cmp(Query a, Query b) {
    	return (be[a.l] ^ be[b.l]) ? be[a.l] < be[b.l] : ((be[a.r] ^ be[b.r]) ? be[a.r] < be[b.r] : a.time < b.time);
    } 
    int main() {
    	n = read(), m = read();
    	int sz = pow(n, 2.0 / 3.0), n1 = ceil((double)n / sz);
    	for (int i = 1; i <= n1; i++)
    		for (int j = (i - 1) * sz + 1; j <= i * sz; j++)
    			be[j] = i;
    	for (int i = 1; i <= n; i++)
    		a[i] = read();
    	for (int i = 1; i <= m; i++) {
    		scanf("%c", &ch);
    		while (ch != 'Q' && ch != 'R')
    			scanf("%c", &ch);
    		if (ch == 'Q') {
    			q[++cntq].l = read(), q[cntq].r = read(), q[cntq].time = cntc, q[cntq].id = cntq;
    		}
    		else if (ch == 'R') {
    			c[++cntc].pos = read(), c[cntc].color = read();
    		}
    	}
    	std::sort(q + 1, q + 1 + cntq, cmp);
    	int L = 1, R = 0, Time = 0;
    	for (int i = 1; i <= m; i++) {
    		int l = q[i].l, r = q[i].r, time = q[i].time;
    		while (L < l)
    			now -= !--cnt[a[L++]];
    		while (L > l)
    			now += !cnt[a[--L]]++;
    		while (R < r)
    			now += !cnt[a[++R]]++;
    		while (R > r)
    			now -= !--cnt[a[R--]];
    		while (Time < time) {
    			Time++;
    			if (l <= c[Time].pos && r >= c[Time].pos)
    				now -= !--cnt[a[c[Time].pos]] - !cnt[c[Time].color]++;
    			std::swap(a[c[Time].pos], c[Time].color);
    		}
    		while (Time > time) {
    			if (l <= c[Time].pos && r >= c[Time].pos)
    				now -= !--cnt[a[c[Time].pos]] - !cnt[c[Time].color]++;
    			std::swap(a[c[Time].pos], c[Time].color);
    			Time--;
    		}
    		ans[q[i].id] = now;
    	}
    	for (int i = 1; i <= cntq; i++)
    		printf("%d
    ", ans[i]);
    	return 0;
    }
    

    折半搜索 (9.30)

    [CEOI2015 Day2]世界冰球锦标赛

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 1e6 + 10, M = 1 << 21;
    int n;
    long long aa[N], m;
    long long suma[M], sumb[M], cnta, cntb;
    long long ans;
    inline int read() {
        int x = 0, k = 1; char c = getchar();
        for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
        for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
        return k ? x : -x;
    }
    inline long long read1() {
        long long x = 0, k = 1; char c = getchar();
        for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
        for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
        return k ? x : -x;
    }
    void dfs(int l, int r, long long sum, long long a[], long long &cnt) {
        if (sum > m)
            return;
        if (l > r) {
            a[++cnt] = sum;
            return;
        }
        dfs(l + 1, r, sum + aa[l], a, cnt);
        dfs(l + 1, r, sum, a, cnt);
    }
    signed main() {
        n = read(), m = read1();
        for (int i = 1; i <= n; i++)
            aa[i] = read1();
        dfs(1, n >> 1, 0, suma, cnta);
        dfs((n >> 1) + 1, n, 0, sumb, cntb);
        std::sort(suma + 1, suma + 1 + cnta);
        for (int i = 1; i <= cntb; i++)
            ans += upper_bound(suma + 1, suma + 1 +cnta, m - sumb[i]) - suma - 1;
        printf("%lld", ans);
        return 0;
    }
    

    树链剖分 (9.30)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10, M = N << 2;
    int n, m, r, Mo, num, from[N], nxt[N], to[N], w[N], w1[N], a[M], lazy[M];
    int son[N], id[N], father[N], depth[N], size[N], top[N], cnt, res;
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    inline void add(int x, int y) { // build tree
    	to[++num] = y, nxt[num] = from[x], from[x] = num;
    }
    void dfs1(int x, int fa, int deep) {
    	depth[x] = deep, father[x] = fa, size[x] = 1;
    	int maxx = -1; // find height son
    	for (int i = from[x]; i; i = nxt[i]) {
    		int y = to[i];
    		if (y == fa) // father
    			continue;
    		dfs1(y, x, deep + 1);
    		size[x] += size[y];
    		if (size[y] > maxx)
    			son[x] = y, maxx = size[y];
    	}
    }
    void dfs2(int x, int Top) { // link top
    	id[x] = ++cnt; // new number
    	w1[cnt] = w[x]; // new value
    	top[x] = Top;
    	if (!son[x]) return; //no sum
    	dfs2(son[x], Top);
    	for (int i = from[x]; i; i = nxt[i]) {
    		int y = to[i];
    		if (y == father[x] || y == son[x]) // father or height son
    			continue;
    		dfs2(y, y); // light son -> link top
    	}
    }
    
    /*********Segment Tree***********/
    inline void pushdown(int x, int y) {
    	int l = x << 1, r = x << 1 | 1;
    	lazy[l] += lazy[x], lazy[r] += lazy[x];
    	a[l] = (a[l] + lazy[x] * (y - (y >> 1))) % Mo;
    	a[r] = (a[r] + lazy[x] * (y >> 1)) % Mo;
    	lazy[x] = 0;	
    }
    void build(int x, int l, int r) {
    	if (l == r) {
    		a[x] = w1[l] % Mo;
    		return;
    	}
    	build(x << 1, l, l + r >> 1);
    	build(x << 1 | 1, (l + r >> 1) + 1, r);
    	a[x] = (a[x << 1] + a[x << 1 | 1]) % Mo;
    }
    void query(int x, int l, int r, int L, int R) {
    	if (L <= l && R >= r) {
    		res = (res + a[x]) % Mo;
    		return;
    	}
    	if (lazy[x])
    		pushdown(x, r - l + 1);
    	if (L <= (l + r >> 1))
    		query(x << 1, l, l + r >> 1, L, R);
    	if (R > (l + r >> 1))
    		query(x << 1 | 1, (l + r >> 1) + 1, r, L, R);
    }
    
    void update(int x, int l, int r, int L, int R, int k) {
    	if (L <= l && R >= r) {
    		lazy[x] += k, a[x] += k * (r - l + 1);
    		return;
    	}
    	if (lazy[x]) pushdown(x, r - l + 1);
    	if (L <= (l + r >> 1))
    		update(x << 1, l, l + r >> 1, L, R, k);
    	if (R > (l + r >> 1))
    		update(x << 1 | 1, (l + r >> 1) + 1, r, L, R, k);
    	a[x] = (a[x << 1] + a[x << 1 | 1]) % Mo;
    }
    /*********Segment Tree***********/
    
    inline void addroad(int x, int y, int k) {
    	k %= Mo;
    	while (top[x] != top[y]) { // not same link
    		if (depth[top[x]] < depth[top[y]])
    			std::swap(x, y);
    		update(1, 1, n, id[top[x]], id[x], k);
    		x = father[top[x]];
    	}
    	if (depth[x] > depth[y])
    		std::swap(x, y);
    	update(1, 1, n, id[x], id[y], k);
    }
    inline int sumroad(int x, int y) {
    	int ans = 0;
    	while (top[x] != top[y]) {
    		if (depth[top[x]] < depth[top[y]])
    			std::swap(x, y);
    		res = 0;
    		query(1, 1, n, id[top[x]], id[x]);
    		ans = (ans + res) % Mo;
    		x = father[top[x]];
    	}
    	if (depth[x] > depth[y])
    		std::swap(x, y);
    	res = 0;
    	query(1, 1, n, id[x], id[y]);
    	return (ans + res) % Mo;
    }
    inline int sumson(int x) {
    	res = 0;
    	query(1, 1, n, id[x], id[x] + size[x] - 1);
    	return res;
    }
    inline void addson(int x, int k) {
    	update(1, 1, n, id[x], id[x] + size[x] - 1, k);
    }
    int main() {
    	n = read(), m = read(), r = read(), Mo = read();
    	for (int i = 1; i <= n; i++)
    		w[i] = read();
    	for (int i = 1; i < n; i++) {
    		int x = read(), y = read();
    		add(x, y), add(y, x);
    	}
    	dfs1(r, 0, 1);
    	dfs2(r, r);
    	build(1, 1, n);
    	while (m--) {
    		int opt = read(), x = read();
    		if (opt == 1) {
    			int y = read(), z = read();
    			addroad(x, y, z);   // (x - y) path -> add z
    		}
    		else if (opt == 2) {
    			int y = read();
    			printf("%d
    ", sumroad(x, y)); // (x - y) path -> sum
    		}
    		else if (opt == 3) {
    			int y = read();
    			addson(x, y); // subtree -> add z
    		}
    		else if (opt == 4) 
    			printf("%d
    ", sumson(x)); // subtree -> sum
    	}
    	return 0;
    }
    

    匈牙利算法 (10.2)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2010;
    int n, m, e, Match[N << 1], ans, ask[N << 1], head[N], cnt;
    struct Node {
        int to, nxt;
    } edge[N * N];
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    inline void add(int u, int v) {
        edge[++cnt] = (Node) {v, head[u]}, head[u] = cnt;
    }
    inline bool found(int x) {
        for (int i = head[x]; i; i = edge[i].nxt) {
            int y = edge[i].to;
            if (ask[y]) continue;
            ask[y] = 1;
            if (!Match[y] || found(Match[y])) {
                Match[y] = x;
                return true;
            }
        }
        return false;
    }
    inline void match() {
        for (int i = 1; i <= n; i++) {
            memset(ask, 0, sizeof(ask));
            if (found(i))
                ans++;
        }
    }
    int main() {
        n = read(), m = read(), e = read();
        for (int i = 1; i <= e; i++) {
            int u = read(), v = read();
            if (v > m || u > n)
                continue;
            add(u, v + n);
        }
        match();
        printf("%d
    ", ans);
        return 0;
    }
    

    Hopcroft-Karp (未)

    //不是我的代码
    /*
    dx[i]表示左集合i顶点的距离编号
    dy[i]表示右集合i顶点的距离编号
    mx[i]表示左集合顶点所匹配的右集合顶点序号
    my[i]表示右集合i顶点匹配到的左集合顶点序号
    */
    #include <bits/stdc++.h>
    #define N 1005
    #define M 1000005
    using namespace std;
    inline int read()
    {
        register int x=0,f=1;register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*f;
    }
    inline void write(register int x)
    {
        if(!x)putchar('0');if(x<0)x=-x,putchar('-');
        static int sta[25];int tot=0;
        while(x)sta[tot++]=x%10,x/=10;
        while(tot)putchar(sta[--tot]+48);
    }
    struct node{
        int to,next;
    }e[M];
    int head[N],tot=0;
    inline void add(register int u,register int v)
    {
        e[++tot]=(node){v,head[u]};
        head[u]=tot;
    }
    int n,m,es,ans;
    int dx[N],dy[N],mx[N],my[N],vis[N],dis;
    inline bool bfs()
    {
        queue<int> q;
        dis=1926081700;
        memset(dx,-1,sizeof(dx));
        memset(dy,-1,sizeof(dy));
        for(register int i=1;i<=n;++i)
            if(mx[i]==-1)
            {
                q.push(i);
                dx[i]=0;
            }
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            if(dx[u]>dis)
                break;
            for(register int i=head[u];i;i=e[i].next)
            {
                int v=e[i].to;
                if(dy[v]==-1)
                {
                    dy[v]=dx[u]+1;
                    if(my[v]==-1)
                        dis=dy[v];
                    else
                    {
                        dx[my[v]]=dy[v]+1;
                        q.push(my[v]);
                            }       
                }   
            }
        }
        return dis!=1926081700;
    }
    inline bool dfs(register int u)
    {
        for(register int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(vis[v]||(dy[v]!=dx[u]+1))
                continue;
            vis[v]=1;
            if(my[v]!=-1&&dy[v]==dis)
                continue;
            if(my[v]==-1||dfs(my[v]))
            {
                my[v]=u;
                mx[u]=v;
                return true;
            }
        }
        return false;
    }
    inline void match()
    {
        memset(mx,-1,sizeof(mx));
        memset(my,-1,sizeof(my));
        while(bfs())
        {
            memset(vis,0,sizeof(vis));
            for(register int i=1;i<=n;++i)
                if(mx[i]==-1&&dfs(i))
                    ++ans;
        }
    }
    int main()
    {
        n=read(),m=read(),es=read();
        while(es--)
        {
            int u=read(),v=read();
            if(v>m)
                continue;
            add(u,v);   
        }   
        match();
        write(ans);
        return 0;
    } 
    

    Kuhn-Munkras (10.5)

    hdu2255

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 110, INF = 0x3f3f3f3f;
    bool tfg[N], tfb[N];
    int b[N], g[N], a[N][N], match[N], slack[N], n;
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    bool pd(int x) {
        tfg[x] = true;
        for (int i = 1; i <= n; i++) {
            if (tfb[i])
                continue;
            int t = b[i] + g[x] - a[x][i];
            if (t == 0) {
                tfb[i] = true;
                if (match[i] == -1 || pd(match[i])) {
                    match[i] = x;
                    return true;
                }
            }
            else 
                slack[i] = std::min(slack[i], t);
        }
        return false;
    }
    inline void KM() {
        memset(match, -1, sizeof(match));
        memset(b, 0, sizeof(b));
        for (int i = 1; i <= n; i++) {
            g[i] = a[i][1];
            for (int j = 2; j <= n; j++)
                g[i] = std::max(g[i], a[i][j]);
        }
        for (int i = 1; i <= n; i++) {
            fill(slack + 1, slack + n + 1, INF);
            while (true) {
                memset(tfb, false, sizeof(tfb));
                memset(tfg, false, sizeof(tfg));    
                if (pd(i))
                    break;
                int d = INF;
                for (int j = 1; j <= n; j++)
                    if (!tfb[j])
                        d = std::min(d, slack[j]);
                for (int j = 1; j <= n; j++) {
                    if (tfg[j])
                        g[j] -= d;
                    if (tfb[j]) b[j] += d; else slack[j] -= d;
                }
            }
        }
    }
    int main() {
        n =  read();
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                a[i][j] = read();
        KM();
        int ans = 0;
        for (int i = 1; i <= n; i++)
            ans += a[match[i]][i];
        printf("%d
    ", ans);
        return 0;
    }
    

    动态dp (10.7)

    题目

    yyb巨佬博客

    #include<bits/stdc++.h>
    using namespace std;
    
    const int INF = -0x3f, N = 1e5 + 10, M = 4e5 + 10;
    
    int n, m, cnt, head[N], to[M], nxt[M], siz[N], fa[N], val[N], son[N], cnt1, id[N], dfn[N], End[N], top1[N], f[N][2], L[N << 2], R[N << 2];
    
    struct Matrix {
    	int mat[2][2];
    
    	Matrix() {
    		memset(mat, INF, sizeof(mat));
    	}
    
    	inline Matrix operator * (Matrix b) {
    		Matrix a;
    		for (int i = 0; i < 2; i++)
    			for (int j = 0; j < 2; j++)
    				for (int k = 0; k < 2; k++)
    					a.mat[i][j] = std::max(a.mat[i][j], mat[i][k] + b.mat[k][j]);
    		return a;
    	}
    
    } Val[N << 2], a[N << 2];
    
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    
    inline void add(int x, int y) {
    	to[++cnt] = y, nxt[cnt] = head[x], head[x] = cnt;
    }
    
    void dfs1(int x) {
    	siz[x] = 1;
    	for (int i = head[x]; i; i = nxt[i]) {
    		int y = to[i];
    		if (y == fa[x])
    			continue;
    		fa[y] = x;
    		dfs1(y);
    		siz[x] += siz[y];
    		if (siz[y] > siz[son[x]]) // height son
    			son[x] = y;
    	}
    }
    
    void dfs2(int x, int Top) {
    	id[x] = ++cnt1, dfn[cnt1] = x, top1[x] = Top, End[Top] = std::max(End[Top], cnt1);
    	f[x][0] = 0, f[x][1] = val[x];
    	Val[x].mat[0][0] = Val[x].mat[0][1] = 0, Val[x].mat[1][0] = val[x];
    	if (son[x] != 0) {
    		dfs2(son[x], Top);
    		f[x][0] += std::max(f[son[x]][0], f[son[x]][1]);
    		f[x][1] += f[son[x]][0];
    	}
    	for (int i = head[x]; i; i = nxt[i]) {
    		int y = to[i];
    		if (y== fa[x] || y == son[x])
    			continue;
    		dfs2(y, y);
    		f[x][0] += std::max(f[y][0], f[y][1]), f[x][1] += f[y][0];
    		Val[x].mat[0][0] += std::max(f[y][0], f[y][1]);
    		Val[x].mat[0][1] = Val[x].mat[0][0], Val[x].mat[1][0] += f[y][0];
    	}
    }
    
    void Build(int l, int r, int x) {
    	L[x] = l, R[x] = r;
    	if (L[x] == R[x]) {
    		a[x] = Val[dfn[L[x]]];
    		return;
    	}
    	Build(L[x], L[x] + R[x] >> 1, x << 1);
    	Build((L[x] + R[x] >> 1) + 1, R[x], x << 1 | 1);
    	a[x] = a[x << 1] * a[x << 1 | 1];
    }
    
    void update(int x, int i) {
    	if (L[i] == R[i]) {
    		a[i] = Val[dfn[x]];
    		return;
    	}
    	if (x <= (L[i] + R[i] >> 1))
    		update(x, i << 1);
    	else
    		update(x, i << 1 | 1);
    	// update(x, (x <= (L[i] + R[i] >> 1)) ? (i << 1) : (i << 1 | 1));
    	a[i] = a[i << 1] * a[i << 1 | 1];
    }
    
    Matrix query(int l, int r, int x) {
    	if (L[x] == l && R[x] == r)
    		return a[x];
    	int mid = L[x] + R[x] >> 1;
    	if (r <= mid) return query(l, r, x << 1);
    	else if (l > mid) return query(l, r, x << 1 | 1);
    	else return query(l, mid, x << 1) * query(mid + 1, r, x << 1 | 1);
    }
    
    void update_path(int x, int y) {
    	Val[x].mat[1][0] += y - val[x], val[x] = y;
    	Matrix a, b;
    	while (x != 0) {
    		a = query(id[top1[x]], End[top1[x]], 1);
    		update(id[x], 1);
    		b = query(id[top1[x]], End[top1[x]], 1), x = fa[top1[x]];
    		Val[x].mat[0][0] += std::max(b.mat[0][0], b.mat[1][0]) - std::max(a.mat[0][0], a.mat[1][0]), Val[x].mat[0][1] = Val[x].mat[0][0];
    		Val[x].mat[1][0] += b.mat[0][0] - a.mat[0][0];
    	}
    }
    
    int main() {
    	n = read(), m = read();
    	for (int i = 1; i <= n; i++)
    		val[i] = read();
    	for (int i = 1; i < n; i++) {
    		int x = read(), y = read();
    		add(x, y), add(y, x);
    	}
    	dfs1(1);
    	dfs2(1, 1);
    	Build(1, n, 1);
    	for (int i = 1; i <= m; i++) {
    		int x = read(), y = read();
    		update_path(x, y);
    		Matrix ans = query(id[1], End[1], 1);
    		printf("%d
    ", std::max(ans.mat[0][0], ans.mat[1][0]));
    	}
    	return 0;
    }
    

    缩点(10.8)

    CF734E Anton and Tree

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10;
    
    int n, color[N];
    vector<int> a[N];
    
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    
    pair<int, int> dfs(int x, int fa, int depth) {
        int sz = a[x].size();
        pair<int, int> tmp = make_pair(depth, x);
        for (int i = 0; i < sz; i++) {
            int y = a[x][i];
            if (y == fa)
                continue;
            if(color[y] != color[x])
                tmp = std::max(tmp, dfs(y, x, depth + 1));
            else 
                tmp = std::max(tmp, dfs(y, x, depth));
        }
        return tmp;
    }
    
    int main() {
        n = read();
        for (int i = 1; i <= n; i++)
            color[i] = read();
        for (int i = 1; i < n; i++) {
            int x = read(), y = read();
            a[x].push_back(y), a[y].push_back(x);
        }
        pair<int, int> tmp = dfs(1, -1, 0);
        tmp = dfs(tmp.second, -1, 0);
        printf("%d
    ", tmp.first + 1 >> 1);
    }
    

    Lucas (10.9)

    inline long long ksm(long long a, long long b) {
        long long ans = 1;
        a = a % Mo;
        for (; b; b >>= 1, a = a * a % Mo)
            if (b & 1) ans = ans * a % Mo;
        return ans;
    }
    
    inline long long C(long long n, long long m) {
        if (m > n) return 0;
        long long a = 1, b = 1;
        for (long long i = 1; i <= m; i++)
            a = a * (n + i - m) % Mo, b = b * i % Mo;
        return a * ksm(b, Mo - 2) % Mo;
    }
    
    inline long long Lucas(long long n, long long m) {
        long long ans = 1;
        for (; n && m; n /= Mo, m /= Mo)
            ans = ans * C(n % Mo, m % Mo);
        return ans;
    }
    

    Simpson 1(10.9)

    题目

    #include<bits/stdc++.h>
    using namespace std;
    
    const double Eps = 1e-6;
    
    double a, b, c, d, L, R;
    
    inline double f(double x) {
        return (c * x + d) / (a * x + b);
    }
    
    inline double Simpson(double L, double R) {
        double mid = (L + R) / 2;
        return ((R - L) * (f(L) + f(R) + 4 * f(mid))) / 6.0;
    }
    
    inline double Solve(double L, double R, double eps, double ans) {
        double mid = (L + R) / 2;
        double l = Simpson(L, mid), r = Simpson(mid, R);
        if (fabs(l + r - ans) <= eps * 15)
            return l + r + (l + r - ans) / 15;
        return Solve(L, mid, eps / 2, l) + Solve(mid, R, eps / 2, r);
    }
    
    inline double Solve(double L, double R, double eps) {
        return Solve(L, R, eps, Simpson(L, R));
    }
    
    int main() {
        scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &L, &R);
        printf("%.6f", Solve(L, R, Eps));
        return 0;
    }
    

    Simpson 2 (10.10)

    #include<bits/stdc++.h>
    using namespace std;
    
    const double Eps = 1e-8;
    
    double a, b, c, d, L, R;
    
    inline double f(double x) {
        return pow(x, a / x - x);
    }
    
    inline double Simpson(double L, double R) {
        double mid = (L + R) / 2;
        return ((R - L) * (f(L) + f(R) + 4 * f(mid))) / 6.0;
    }
    
    inline double Solve(double L, double R, double eps, double ans) {
        double mid = (L + R) / 2;
        double l = Simpson(L, mid), r = Simpson(mid, R);
        if (fabs(l + r - ans) <= eps * 15)
            return l + r + (l + r - ans) / 15;
        return Solve(L, mid, eps / 2, l) + Solve(mid, R, eps / 2, r);
    }
    
    inline double Solve(double a, double b) {
        return Solve(a, b, Eps, Simpson(a, b));
    }
    
    int main() {
        scanf("%lf", &a);
        if (a < 0) 
            return puts("orz"), 0;
        printf("%.5f", Solve(Eps, 20.0));
        return 0;
    }
    

    (mathcal{01trie})

    题目

    #include<bits/stdc++.h>
    #define pow(x, i) (x >> i)
    using namespace std;
    
    const int N = 6e6 + 10, M = 30;
    
    int cnt[N], trie[N][2], tot = 1, n;
    
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    
    inline void add(int x, int dg) {
        int p = 1;
        for (int i = M; i >= 0; --i) {
            if (dg == 1) trie[p][(pow(x, i) & 1)] = (trie[p][(pow(x, i) & 1)] != 0) ? trie[p][(pow(x, i) & 1)] : (++tot);
            p = trie[p][(pow(x, i) & 1)], cnt[p] += dg;
        }
    }
    
    inline int ask(int x, int y) {
        int p = 1;
        int sum = 0;
        for (int i = M; i >= 0; i--) {
            int t = (pow(y, i) & 1), t1 = (pow(x, i) & 1);
            if (t)
                sum += cnt[trie[p][t1]], p = trie[p][t1 ^ 1];
            else 
                p = trie[p][t1];
        }
        return sum;
    }
    
    int main() {
        n = read();
        while (n--) {
            int opt = read(), x = read();
            if (opt == 1)
                add(x, 1);
            else if (opt == 2)
                add(x, -1);
            else if (opt == 3) {
                int y = read();
                printf("%d
    ", ask(x, y));
            }
        }
        return 0;
    }
    

    树的重心

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N =  3e5 + 10;
    
    struct Node {
        int to, nxt;
    } edge[N << 1];
    
    int cnt, n, m, Fa[N], sz[N], ans[N], head[N];
    
    inline int read() {
        int x = 0, k = 1; char c = getchar();
        for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
        for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
        return k ? x : -x;
    }
    
    inline void Build(int x, int y) {
        edge[++cnt].to = x, edge[cnt].nxt = head[y], head[y] = cnt;
    }
    
    void dfs(int x, int fa) {
        int res = 0;
        sz[x] = 1,  ans[x] = x;
        for (int i = head[x]; i; i = edge[i].nxt) {
            int y = edge[i].to;
            if (y == fa)
                continue;
            dfs(y, x);
            sz[x] += sz[y], res = (sz[y] > sz[res]) ? y : res;
        }
    
        if ((sz[res] << 1) > sz[x])
            for (ans[x] = ans[res]; ((sz[x] - sz[ans[x]]) << 1) > sz[x]; ans[x] = Fa[ans[x]]);
    }
    
    int main() {
        n = read(), m = read();
        for (int i = 2; i <= n; i++) {
            Fa[i] = read();
            Build(i, Fa[i]);
            Build(Fa[i], i);
        }
    
        dfs(1, 0);
    
        while (m--) {
            int x = read();
            printf("%d
    ", ans[x]);
        }
        return 0;
    }
    

    二分图多重匹配(未)

    链接

    2-SAT

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #include <vector>
    
    const int N = 1e6;
    
    int n, m, num, cnt, NUM, u1, v1, u2, v2, dfn[N << 2], low[N << 2], Stack[N << 2], f[N << 2], head[N << 2], a, x, b, y, tot;
    bool vis[N << 2];
    
    struct Node {
        int to, nxt, from;
    } edge[N << 2];
    
    inline int read() {
    	int x = 0, k = 1; char c = getchar();
    	for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    	for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    	return k ? x : -x;
    }
    
    void Tarjan(int x, int fa) {
        dfn[x] = low[x] = ++num, vis[x] = true, Stack[++cnt] = x;
        bool tf = 0;
        for (int i = head[x]; i; i = edge[i].nxt) {
            int y = edge[i].to;
            if (y == fa && !tf) {
                tf = 1;
                continue;
            }
            if (!dfn[y]) {
                Tarjan(y, x);
                low[x] = std::min(low[x], low[y]);
            }
            else if (!f[y]) {
                low[x] = std::min(low[x], dfn[y]);
            }
        }
        if (dfn[x] == low[x]) {
            NUM++;
            for (; Stack[cnt] != x; ) f[Stack[cnt]] = NUM, vis[Stack[cnt]] = 0, --cnt;
            f[Stack[cnt]] = NUM, vis[Stack[cnt]] = 0;
            cnt--;
        }
    }
    
    inline void add(int x, int y) {
        edge[++tot].to = y, edge[tot].from = x, edge[tot].nxt = head[x], head[x] = tot;
    }
    
    int main() {
        n = read(), m = read();
        for (int i = 1; i <= m; i++) {
            a = read(), x = read(), b = read(), y = read();
            if (x == 0)
                u1 = a + n, v2 = a;
            else if (x == 1)
                u1 = a, v2 = a + n;
            if (y == 0)
                v1 = b, u2 = b + n;
            else if (y == 1)
                v1 = b + n, u2 = b;
            add(u1, v1), add(u2, v2);
        }
        for (int i = 1; i <= 2 * n; i++)
            if (!dfn[i])
                Tarjan(i, 0);
        for (int i = 1; i <= n; i++) 
            if (f[i] == f[i + n]) {
                printf("IMPOSSIBLE
    ");
                return 0;
            }
        printf("POSSIBLE
    ");
        for (int i = 1; i <= n; i++) 
            printf("%d ", f[i] > f[i + n] ? 1 : 0);
        return 0;
    }
    

    WQS 二分 (未)

    学习链接

    ZAGER

  • 相关阅读:
    转:Jmeter之Bean shell使用(一)
    转:Curl详解
    转:MIME(Multipurpose Internet Mail Extensions)类型
    转:Tomcat配置
    转:windows 7系统安装与配置Tomcat服务器环境
    转:Apache POI Tutorial
    转:Busy Developers' Guide to HSSF and XSSF Features
    转:Java实现几种常见排序方法
    转:JAVA强制类型转换
    转:Java的各种类型转换汇总
  • 原文地址:https://www.cnblogs.com/wjnclln/p/11585442.html
Copyright © 2011-2022 走看看