• 2019ICPC南昌邀请赛


    A - PERFECT NUMBER PROBLEM

    题意

    找到前五个因数之和(除了自己)是本身的数

    思路

    (nsqrt n) 暴力打表

    6, 28, 496, 8128, 33550336

    M - Subsequence

    题意

    询问是否是子序列

    思路

    直接暴力

    #include<bits/stdc++.h>
    using namespace std;
    
    int mp[26][100010];
    int cnt[26];
    char s[100010], p[1010];
    int T;
    int main() {
    	scanf("%s", s + 1);
    	int x = strlen(s + 1);
    	for (int i = 1; i <= x; i++) {
    		mp[s[i] - 'a'][cnt[s[i] - 'a']++] = i;
    	}
    	scanf("%d", &T); getchar();
    	while (T--) {
    		scanf("%s", p + 1);
    
    		int now = 0, f = 1;
    		int len = strlen(p + 1);
    		for (int i = 1; i <= len; i++) {
                int idx = p[i] - 'a';
    			int pos = upper_bound(mp[idx], mp[idx] + cnt[idx], now) - mp[idx];
    			if (pos == cnt[idx]) {
    				f = 0;
    				break;
    			}
    			now = mp[idx][pos];
    		}
    		if (f)puts("YES");
    		else puts("NO");
    	}
    }
    

    H - Coloring Game

    (f[n] = 2*2*3^{n-2})

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    const int mod = 1000000007;
    
    int qpow(int a, int p) {
    	int ans = 1;
    	while (p) {
    		if (p & 1)ans = (ans * a) % mod;
    		a = a * a % mod;
    		p >>= 1;
    	}
    	return ans;
    }
    
    signed main() {
    	int n; cin >> n;
    	if (n == 1)cout << 1 << endl;
    	else cout << 4 * qpow(3, n - 2) % mod << endl;
    }
    

    K - MORE XOR

    找规律

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5 + 10;
    int A[N];
    
    int T, n, m;
    int f[N];
    
    int main() {
    	scanf("%d", &T);
    	while (T--) {
    		scanf("%d", &n);
    		for (int i = 1; i <= n; i++) {
    			scanf("%d", A + i);
    			f[i] = A[i];
    			if (i > 4)f[i] ^= f[i - 4];
    		}
    		scanf("%d", &m);
    		while (m--) {
    			int l, r;
    			scanf("%d%d", &l, &r);
    			if (l == r) {
    				printf("%d
    ", A[l]);
    				continue;
    			}
    			int len = r - l + 1;
    			int ans = 0;
    			if (len % 2 == 0) {
    				int x = len / 2;
    				if (x % 2 == 0)ans = 0;
    				else ans = f[r] ^ f[l + 1] ^ A[l + 1] ^ f[r - 1] ^ f[l] ^ A[l];;
    			}
    			else {
    				int x = len / 2;
    				if (x % 2 == 0) {
    					ans = f[r] ^ f[l] ^ A[l];
    				}
    				else {
    					ans = f[r - 1] ^ f[l + 1] ^ A[l + 1];
    				}
    			}
    			printf("%d
    ", ans);
    		}
    	}
    }
    

    J - Distance on the tree

    查询树上路径上边权小于等于 (k) 的边数

    写的树剖加主席树,挂了

    /*
     * @Author: zhl
     * @Date: 2020-11-9 20:36:59
     */
    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i = a;i <= b;i++)
    #define repE(i,u) for(int i = head[u];i;i = E[i].next)
    #define mid ((l+r)>>1)
    
    using namespace std;
    const int N = 5e5 + 10;
    int A[N];
    int n, m;
    
    struct Edge {
    	int to, next, w;
    }E[N << 1];
    
    int head[N], tot;
    void addEdge(int from, int to,int w) {
    	E[++tot] = Edge{ to,head[from],w };
    	head[from] = tot;
    }
    
    int fa[N], sz[N], Tfa[N], dep[N], son[N];
    
    //dfs1处理dep,sz,fa,son(重儿子)
    void dfs1(int u, int p) {
    	fa[u] = p;
    	dep[u] = dep[p] + 1;
    	sz[u] = 1;
    	int mx = -1;
    	repE(i, u) {
    		int v = E[i].to;
    		if (v == p)continue;
    		dfs1(v, u);
    		sz[u] += sz[v];
    		if (sz[v] > mx)mx = sz[v], son[u] = v;
    	}
    }
    
    int cnt;
    int id[N], val[N], top[N];
    //dfs2 剖分树链
    void dfs2(int u, int topf, int w) {
    	id[u] = ++cnt;
    	
    	val[cnt] = w;
    	top[u] = topf;
    	if (!son[u])return;
    
    	int x = 0;
    	repE(i, u)if (E[i].to == son[u]) x = E[i].w;
    	dfs2(son[u], topf, x);
    
    	repE(i, u) {
    		int v = E[i].to;
    		if (v == fa[u] or v == son[u])continue;
    		dfs2(v, v, E[i].w);
    	}
    }
    
    
    
    
    int W[N];//边权
    int root[N]; 
    int cntW;
    int getid(int x) {
    	return lower_bound(W + 1, W + cntW + 1, x) - W;
    }
    int L[N << 5], R[N << 5], sum[N << 5];
    int Tot;
    
    
    int build(int l, int r) {
    	int u = ++Tot;
    	sum[u] = 0;
    	if (l < r) {
    		L[u] = build(l, mid);
    		R[u] = build(mid + 1, r);
    	}
    	return u;
    }
    
    int insert(int pre, int l, int r, int pos) {
    	int u = ++Tot;
    	L[u] = L[pre];
    	R[u] = R[pre];
    	sum[u] = sum[pre] + 1;
    
    	if (l >= r)return u;
    
    	if (pos <= mid) {
    		L[u] = insert(L[pre], l, mid, pos);
    	}
    	else {
    		R[u] = insert(R[pre], mid + 1, r, pos);
    	}
    	return u;
    }
    int query(int rt_x, int rt_y,int l,int r, int k) {
    	if (l == r) {
    		return sum[rt_y] - sum[rt_x];
    	}
    	int num = sum[L[rt_y]] - sum[L[rt_x]];//区间内,左半区间的数的数量
    
    	if (k <= mid) return query(L[rt_x], L[rt_y], l, mid, k);
    	else return num + query(R[rt_x], R[rt_y], mid + 1, r, k);
    
    	return 0;
    }
    int query_path(int a, int b,int k) {
    	int ans = 0; int x, y;
    	int v = upper_bound(W + 1, W + cntW + 1, k) - W - 1;
    	if (!v)return 0;
    	while (top[a] != top[b]) {
    		if (dep[top[a]] < dep[top[b]])swap(a, b);
    		x = id[top[a]]; y = id[a];
    		ans += query(root[x-1], root[y], 1, cntW, v);
    		a = fa[top[a]];
    	}
    	if (a == b)return ans;
    	if (dep[a] > dep[b])swap(a, b);
    	x = id[a]; y = id[b];
    	ans += query(root[x-1], root[y], 1,cntW, v);
    	return ans;
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    
    	for (int i = 1; i < n; i++) {
    		int x, y, z;
    		scanf("%d%d%d", &x, &y, &z);
    		W[i] = z;
    		addEdge(x, y, z); addEdge(y, x, z);
    	}
    	W[n] = 0x3f3f3f3f;
    	sort(W + 1, W + n + 1);
    	cntW = unique(W + 1, W + n + 1) - W - 1;
    	root[0] = build(1, cntW);
    
    	dfs1(1, 0);
    	dfs2(1, 1, 0x3f3f3f3f);
    
    	for (int i = 1; i <= n; i++) {
    		root[i] = insert(root[i - 1], 1, cntW, getid(val[i]));
    	}
    
    	while (m--) {
    		int a, b, k;
    		scanf("%d%d%d", &a, &b, &k);
    		printf("%d
    ", query_path(a, b, k));
    	}
    }
    

    换了一个写法,就 A 了???

    int query_path(int a, int b, int k) {
    	int lca = LCA(a, b);
    	int v = upper_bound(W + 1, W + 1 + cntW, k) - W - 1;
    	if (!v)return 0;
    	int ans = query(root[0], root[a], 1, cntW, 1, v) + query(root[0], root[b], 1, cntW, 1, v) - 2 * query(root[0], root[lca], 1, cntW, 1, v);
    	//if (val[lca] <= k)ans--;
    	return ans;
    }
    
    /*
     * @Author: zhl
     * @Date: 2020-11-10 20:36:59
     */
    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i = a;i <= b;i++)
    #define repE(i,u) for(int i = head[u];i;i = E[i].next)
    #define mid ((l+r)>>1)
    
    using namespace std;
    const int N = 5e5 + 10;
    int n, m;
    
    struct Edge {
    	int to, next, w;
    }E[N << 1];
    
    int head[N], tot;
    void addEdge(int from, int to, int w) {
    	E[++tot] = Edge{ to,head[from],w };
    	head[from] = tot;
    }
    
    int fa[N], sz[N], Tfa[N], dep[N], son[N];
    
    //dfs1处理dep,sz,fa,son(重儿子)
    void dfs1(int u, int p) {
    	fa[u] = p;
    	dep[u] = dep[p] + 1;
    	sz[u] = 1;
    	int mx = -1;
    	repE(i, u) {
    		int v = E[i].to;
    		if (v == p)continue;
    		dfs1(v, u);
    		sz[u] += sz[v];
    		if (sz[v] > mx)mx = sz[v], son[u] = v;
    	}
    }
    
    int cnt;
    int id[N], val[N], top[N];
    //dfs2 剖分树链
    
    
    
    
    
    int W[N];//边权
    int root[N];
    int cntW;
    int getid(int x) {
    	return lower_bound(W + 1, W + cntW + 1, x) - W;
    }
    int L[N << 5], R[N << 5], sum[N << 5];
    int Tot;
    
    
    int build(int l, int r) {
    	int u = ++Tot;
    	if (l < r) {
    		L[u] = build(l, mid);
    		R[u] = build(mid + 1, r);
    	}
    	return u;
    }
    
    int insert(int pre, int l, int r, int pos) {
    	int u = ++Tot;
    	L[u] = L[pre];
    	R[u] = R[pre];
    	sum[u] = sum[pre] + 1;
    
    	if (l >= r)return u;
    
    	if (pos <= mid) {
    		L[u] = insert(L[pre], l, mid, pos);
    	}
    	else {
    		R[u] = insert(R[pre], mid + 1, r, pos);
    	}
    	return u;
    }
    int query(int rt_x, int rt_y, int l, int r, int Lq, int Rq) {
    	if (Lq <= l and r <= Rq) {
    		return sum[rt_y] - sum[rt_x];
    	}
    	int num = sum[L[rt_y]] - sum[L[rt_x]];//区间内,左半区间的数的数量
    	int res = 0;
    
    	if (Lq <= mid) res += query(L[rt_x], L[rt_y], l, mid, Lq, Rq);
    	if (Rq > mid) res += query(R[rt_x], R[rt_y], mid + 1, r, Lq, Rq);
    	return res;
    }
    
    int LCA(int a, int b) {
    	while (top[a] != top[b]) {
    		if (dep[top[a]] < dep[top[b]])swap(a, b);
    		a = fa[top[a]];
    	}
    	if (dep[a] > dep[b])swap(a, b);
    	return a;
    }
    
    int query_path(int a, int b, int k) {
    	int lca = LCA(a, b);
    	int v = upper_bound(W + 1, W + 1 + cntW, k) - W - 1;
    	if (!v)return 0;
    	int ans = query(root[0], root[a], 1, cntW, 1, v) + query(root[0], root[b], 1, cntW, 1, v) - 2 * query(root[0], root[lca], 1, cntW, 1, v);
    	//if (val[lca] <= k)ans--;
    	return ans;
    }
    
    void dfs2(int u, int topf, int w) {
    	id[u] = ++cnt;
    
    	val[cnt] = w;
    	top[u] = topf;
    	root[u] = insert(root[fa[u]], 1, cntW, getid(w));
    	if (!son[u])return;
    
    	int x = 0;
    	repE(i, u)if (E[i].to == son[u]) x = E[i].w;
    
    	dfs2(son[u], topf, x);
    
    	repE(i, u) {
    		int v = E[i].to;
    		if (v == fa[u] or v == son[u])continue;
    		dfs2(v, v, E[i].w);
    	}
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    
    	for (int i = 1; i < n; i++) {
    		int x, y, z;
    		scanf("%d%d%d", &x, &y, &z);
    		W[i] = z;
    		addEdge(x, y, z); addEdge(y, x, z);
    	}
    	W[n] = 0x3f3f3f3f;
    	sort(W + 1, W + n + 1);
    	cntW = unique(W + 1, W + n + 1) - W - 1;
    	root[0] = build(1, cntW);
    
    	dfs1(1, 0);
    	dfs2(1, 1, 0x3f3f3f3f);
    
    
    
    	while (m--) {
    		int a, b, k;
    		scanf("%d%d%d", &a, &b, &k);
    		printf("%d
    ", query_path(a, b, k));
    	}
    }
    
    /*
    5 400
    1 2 7
    1 3 4
    2 4 5
    3 5 2
    2 3 1000000000
    4 5 1000000000
    */
    
  • 相关阅读:
    mysql慢日志设置
    CURL模拟登陆
    违法图片检测
    PHP取二进制文件头快速判断文件类型
    重写session
    mysql处理高并发,防止库存超卖
    mysql中使用update select
    PHP中使用Luhn算法校验信用卡及借记卡卡号
    红包算法
    DIV当textarea使用,在聚焦的时候将光标移动到内容的末尾
  • 原文地址:https://www.cnblogs.com/sduwh/p/13955590.html
Copyright © 2020-2023  润新知