• 模板


    今天(2017.11.08)开始打板子。

    一、读入输出优化

      注意:数组类型和负号。

    #include <cstdio>
    
    int read() {
    	int x = 0, f = 1;
    	char ch = getchar();
    	while (ch > '9' || ch < '0') ch == '-' && (f = -1), ch = getchar();
    	while (ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	return x * f;
    }
    
    void pf(int x) {                         // 如果x小于10,直接输出,否则先输出十位及以上部分,然后输出个位。如果是负数,先输出‘-’,再当成正数输出即可。
    	if (x < 0) putchar('-'), x = -x;       // 递归版输出优化,听说效率玄学。
    	if (x > 9) pf(x / 10);
    	putchar(x % 10 + '0');
    }
    	
    int main() {
    	int a = read();
    	pf(a);
    }                        
    

    二、并查集

      例题传送门

      模板:

    #include <cstdio>
    
    const int MAXN = 5000 + 7;
    
    int dad[MAXN], n, m, p;
    /******************只有这两行******************************************************/
    int getdad(int x) {
    	return x == dad[x] ? x : getdad(dad[x]);
    }
    
    void join(int x, int y) {
    	int a = getdad(x), b = getdad(y);
    	if (a != b) dad[a] = getdad(b);
    }
    /*******************是主代码。*****************************************************/

    int main() { scanf("%d%d%d", &n, &m, &p); for (int i = 1; i <= n; i++) dad[i] = i; for (int i = 1, x, y; i <= m; i++) scanf("%d%d", &x, &y), join(x, y); for (int i = 1, x, y; i <= p; i++) { scanf("%d%d", &x, &y); int a = getdad(x), b = getdad(y); puts(a == b ? "Yes " : "No "); } return 0; }

    三、树状数组与线段树

      传送门

      树状数组:http://blog.csdn.net/qq_21841245/article/details/43956633

      biu

    树状数组针对的是加上某值,如果是“改为某值”,则操作时加上的是(要改的值-原本的值)。

    #include <cstdio>
    
    const int MAXN = 1e5 + 7;
    
    int n, m;
    
    struct Node {
    	int tree[MAXN];
    	void add(int x, int v) {			// 单点更新 
    		while (x <= n) {
    			tree[x] += v;
    			x += x & (-x);		
    		}
    	}	
    	
    	int sum(int k) {					// 区间求和 
    		int ans = 0;
    		while (k) {	
    			ans += tree[k];
    			k -= k & (-k);
    		}
    		return ans;
    	}
    } T;
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 1, v; i <= n; i++) {
    		scanf("%d", &v);
    		T.add(i, v);
    	}
    	scanf("%d", &m);
    	for (int i = 1; i <= m; i++) {
    		int x, a, b;
    		scanf("%d%d%d", &x, &a, &b);
    		if (x == 1) T.add(a, b);
    		else printf("%d
    ", T.sum(b) - T.sum(a - 1));
    	}
    	
    	return 0;
    }
    

    四、Kruskal

      传送

    #include <cstdio>
    #include <algorithm>
    
    const int MAXN = 107 * 3;
    
    int n, m, cnt, dad[MAXN], size[MAXN], ans;
    
    struct Edge {
    	int from, to, pow;
    	bool operator<(const Edge p) const {
    		return pow < p.pow;
    	}
    } edge[MAXN];
    
    int get(int x) {
    	return dad[x] == x ? x : get(dad[x]);
    }
    
    void join(int x, int y) {
    	int a = get(x), b = get(y);
    	if (size[a] < size[b]) dad[a] = b, size[b] += size[a];
    	else dad[b] = a, size[a] += size[b];
    }
    
    int main() {
    	while (scanf("%d%d", &n ,&m) == 2) {
    		ans = 0;
    		if (n == 0) break;
    		for (int i = 1; i <= m; i++) dad[i] = i, size[i] = 1;
    		for (int i = 1; i <= n; i++) {
    			int x, y, z;
    			scanf("%d%d%d", &x, &y, &z);
    			edge[i].from = x;
    			edge[i].pow = z;
    			edge[i].to = y; 
    		}
    		
    		std::sort(edge + 1, edge + n + 1);
    		
    		int cnt = 0;
    		for (int i = 1; i <= n; i++) {
    			int f = edge[i].from, t = edge[i].to;
    			if (get(f) != get(t)) {
    				join(f, t);
    				cnt++;
    				ans += edge[i].pow;
    			}
    		}
    		
    		if (cnt < m - 1) printf("?
    ");
    		else printf("%d
    ", ans);
    	}
    	return 0;
    } 
    

    五、归并排序

      应用:求逆序对

    #include <iostream>
    #include <cstdio>
    
    const int MAXN = 100050;
    
    int n, a[MAXN], l[MAXN];
    long long count;
     
    void M(int s, int mid , int e) {
    	int i = s, j = mid + 1, k = 1;
    	
    	while (i <= mid && j <= e) {
    		if (a[i] <= a[j]) l[k++] = a[i++];
    		else l[k++] = a[j++], count += mid + 1 - i;						// 求逆序对数关键操作 
    	}
    	
    	while (i <= mid) l[k++] = a[i++];
    	while (j <= e) l[k++] = a[j++];
    	
    	for (int i = 1, j = s; j <= e; j++, i++) a[j] = l[i];				// !!
    }
    
    void MS(int s, int e) {
    	if (!(e - s)) return ;
    	else {
    		int mid = (e + s) / 2;	
    		MS(s, mid);
    		MS(mid + 1, e);
    		M(s, mid, e);
    	}
    }
    
    int main() {
    	scanf("%d", &n);
    	
    	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    
    	MS(1, n);
    	
    	printf("%lld
    ", count);
    
    	for (int i = 1; i <= n; i++) printf("%d ", a[i]);
    	
    	return 0;
    }
    

    六、生无可恋的线段树

    #include <cstdio>
    #include <algorithm>
    
    const int MAXN = 1e5 + 7;
    
    int n, m;
    
    struct Node {
    	int tag, pow, l, r;
    	Node *lc, *rc;
    	Node () {}
    	Node (int l, int r, Node *lc, Node *rc) : tag(0), pow(0), l(l), r(r), lc(lc), rc(rc) {}
    } *cur, *root, node[MAXN * 4];
    
    Node *Build(int l, int r) {
    	int mid = l + ((r - l)>> 1);
    	return l == r ? new (cur++)Node(l, r, NULL, NULL) : new (cur++)Node(l, r, Build(l, mid), Build(mid + 1, r)); 
    }
    
    void Cover(Node *v, int delta) {
    	v->pow += (v->r - v->l + 1) * delta;
    	v->tag += delta; 
    }
    
    void PushDown(Node *v) {
    	if (v->tag) Cover(v->lc, v->tag), Cover(v->rc, v->tag), v->tag = 0;
    }
    
    void Update(Node *v, int l, int r, int delta) {
    	if (v->r < l || v->l > r) return ;
    	else if (l <= v->l && r >= v->r) Cover(v, delta);
    	else PushDown(v), Update(v->lc, l, r, delta), Update(v->rc, l, r, delta), v->pow = v->lc->pow + v->rc->pow; 
    }
    int Q(Node *v, int l, int r) {
    	if (v->r < l || v->l > r) return 0;
    	else if (l <= v->l && r >= v->r) return v->pow;
    	else return PushDown(v), Q(v->lc, l, r) + Q(v->rc, l, r); 
    }
    
    int main() {
    	cur = node;
    	scanf("%d", &n);
    	root = Build(1, n);
    	
    	for (int i = 1, v; i <=n; i++) 
    		scanf("%d", &v), Update(root, i, i, v); 
    	
    	scanf("%d", &m);
    	for (int i = 1; i <= m; i++) {
    		int z, x, y;
    		scanf("%d%d%d", &z, &x, &y);
    		if (z == 1) Update(root, x, x, y);
    		else printf("%d
    ", Q(root, x, y));
    	}
    	return 0;
    } 
    

     每次写线段树总会出点错... ...

      这次份的:

      ① 不加 #include <algorithm> 调了一个下午才发现... ...

       后果:  

          

          

        ② Q(){} 函数最后那种情况没写 ‘+’。

          

        ③ 每次写都犯的:

          Update 和 Q 里第二种情况是

          当前节点代表的区间被要进行操作的区间包含

          而不是 要进行操作的区间被当前节点代表的区间包含。

    七、二分

    #include <cstdio>
    
    const int MAXN = 5e4 + 7;
    
    int s, n, m, a[MAXN];
    
    int check(int x) {
    	int last = 0, re = 0;
    	for (int i = 1; i <= n + 1; i++) 
    		if (a[i] - last < x) re++;
    		else last = a[i];
    	
    	return re;
    }
    
    int main() {
    	scanf("%d%d%d", &s, &n, &m);
    	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    	a[n + 1] = s;
    	
    	int l = 1, r = s, ans = 0;
    	while (l <= r) {
    		int mid = (l + r) >> 1;
    		int f = check(mid);
    //		printf("when mid = %d, f = %d
    ", mid, f);
    		if (f <= m) l = mid + 1, ans = mid;
    		else r = mid - 1; 
    	}
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    } 
    

      错误详见

  • 相关阅读:
    Window Phone 8手电筒
    Wp检查手机网络状态
    Wp 导航到手机定位设置页面
    Wp8 读取手机信息
    移动端丨-webkit-overflow-scrolling:touch属性导致页面卡住
    小程序丨canvas内容自适应不同尺寸屏幕
    钉钉自带浏览器版本过低,导致Object.assign不兼容...
    HTTP中GET与POST的区别
    git丨Push rejected: Push to origin/master was rejected
    小程序丨嵌套循环
  • 原文地址:https://www.cnblogs.com/ExileValley/p/7802207.html
Copyright © 2020-2023  润新知