zoukankan      html  css  js  c++  java
  • 4-7考试总结

    $$4-7$$

    • 第二题是密码锁就直接发出来了,第一题的话又写了一天
    • 自己垃圾,无话可说
    • 总结一下(LCT)简单的子树信息维护要怎么做,以维护子树大小为例,我们对每个子树维护两个信息,一个是子树总大小,一个是虚树的总大小,能够发现我们如果能够快速处理虚树的大小,问题就得到了解决;观察(LCT)什么时候会添加、减少虚儿子,(access and link!),所以在进行这两个操作的时候判断一下就可以了,但是注意这样只能维护可增减的信息,最大值我就完全不会
    • 这道题只需要有大小为(K)的联通块,考虑魔法森林的解法,一样从按照(A)小到大插入边,维护(B)的联通块,可以发现一个联通块有用的信息一定可以表示成一棵树(就是和魔法森林那题差不多),然后考虑能不能试着减少(B),如果当前有(>=K)的连通块这条最大边是一定没有意义的,因为此时更新的答案一定会比不删这条边的答案优,然后维护(>=K)连通块个数以及连通块大小就可以了
    • 吐槽:感觉学子树信息就学了半天看了,一中午哑舍下午头都是昏的加上(LCT)的代码好久没写又回忆了好久,下午调的时候一直不清醒,晚上状态反而好多了,xjb乱写也能调过,结果最后是(push\_up)的时候没注意重新赋初值,然后删边就爆炸了
    • 放个代码感慨一下吧
    #include <bits/stdc++.h>
    
    typedef std::pair<int, int> PII;
    
    #define a first
    #define b second
    
    inline int read(int Num = 0, int Flag = 1)
    {
    	char ch = getchar();
    	for (; !isdigit(ch); ch = getchar()) 
    		if (ch == '-')
    			Flag = -1;
    	for (;  isdigit(ch); ch = getchar())
    		Num = Num * 10 + ch - '0';
    	return Num *= Flag;
    }
    
    template <typename T> bool chkmax(T &a, T b) { return a < b? a = b, true : false; }
    template <typename T> bool chkmin(T &a, T b) { return a > b? a = b, true : false; }
    
    const int mx_n = 3e5 + 5;
    const int mx_m = 5e5 + 5;
    const int inf = 2e9 + 5;
    
    int N, M, K;
    int a[mx_n], b[mx_n];
    
    //int cur;
    struct Edge
    {
    	int u, v, wa, wb;
    	bool operator < (const Edge& rhs)const
    	{
    		return wa < rhs.wa;
    	}
    }edge[mx_m];
    
    int tot;
    
    struct Link_Cut_Tree
    {
    static const int mx_node = (mx_n + mx_m) * 2;
    
    int fa[mx_node];
    int ch[mx_node][2];
    
    int isv[mx_node];
    int sz_all[mx_node];
    int sz_sub[mx_node];
    
    int stk[mx_node];
    int rev[mx_node];
    PII maxb[mx_node];
    
    inline int prefer(int x)
    {
    //	assert(!isrt(x));
    	return ch[fa[x]][1] == x;
    }
    
    inline bool isrt(int x)
    {
    	return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
    }
    
    inline void push_up(int h)
    {
    	sz_all[h] = (h <= N) + sz_sub[h];
    	if (h > N) maxb[h] = PII(edge[h - N].wb, h - N);
    	else maxb[h] = PII(0, 0);
    	for (int i = 0; i < 2; ++i) {
    		chkmax(maxb[h], maxb[ch[h][i]]);
    		sz_all[h] += sz_all[ch[h][i]];
    	}
    }
    
    inline void push_down(int h)
    {
    	if (rev[h]) {
    		rev[ch[h][0]] ^= 1, rev[ch[h][1]] ^= 1;
    		std::swap(ch[h][0], ch[h][1]);
    		rev[h] = 0;
    	}
    }
    
    void rotate(int x, int ty)
    {
    	int y = fa[x];
    	if (!isrt(y)) ch[fa[y]][prefer(y)] = x; fa[x] = fa[y];
    	ch[y][!ty] = ch[x][ty]; fa[ch[x][ty]] = y;
    	ch[x][ty] = y; fa[y] = x;
    	push_up(y);
    	push_up(x);
    }
    
    void pass_tag(int u)
    {
    	int top = 0; stk[++top] = u;
    	for (int i = u; !isrt(i); i = fa[i]) stk[++top] = fa[i];
    	for (int i = top; i >= 1; --i) push_down(stk[i]);
    }
    
    void splay(int h)
    {
    	pass_tag(h);
    	for (int ty; !isrt(h); rotate(h, !ty)) {
    		ty = prefer(h);
    		if (!isrt(fa[h]) && prefer(fa[h]) == ty) rotate(fa[h], !ty);
    	}
    }
    
    void access(int u)
    {
    	for (int v = 0; u; v = u, u = fa[u]) {
    		splay(u);
    		sz_sub[u] += sz_all[ch[u][1]];
    		sz_sub[u] -= sz_all[v];
    		ch[u][1] = v; push_up(u);
    	}
    //	fprintf(stderr, "end
    ");
    }
    
    void make_root(int u)
    {
    	access(u); splay(u), rev[u] ^= 1;
    }
    
    int find(int u)
    {
    	access(u); splay(u);
    	for (; ch[u][0];) u = ch[u][0];
    	splay(u);
    	return u;
    }
    
    PII query(int u, int v)
    {
    	make_root(u); access(v), splay(v);
    	return maxb[v];
    }
    
    void cut(int u, int v)
    {
    //	assert(find(u) == find(v));
    	make_root(u);
    	access(v);
    	splay(v);
    //	if (cur == 6) fprintf(stderr, "!
    ");
    //	assert(ch[v][0] == u);
    //	assert(v == fa[u]);
    //	assert(sz_all[u] - sz_sub[u] == 1);
    
    	int sz1 = sz_all[u];
    	int sz0 = sz_all[v] - sz1;
    //	fprintf(stderr, "%d %d
    ", u, v);
    
    	tot -= sz_all[v] >= K;
    	tot += sz1 >= K;
    	tot += sz0 >= K;
    
    	ch[v][0] = 0, fa[u] = 0;
    	push_up(v);
    }
    
    void link(int u, int v)
    {
    //	assert(find(u) != find(v));
    	make_root(u);
    	make_root(v); 
    	tot -= sz_all[u] >= K;
    	tot -= sz_all[v] >= K;
    
    	fa[v] = u;
    	sz_sub[u] += sz_all[v];
    	push_up(u);
    	tot += sz_all[u] >= K;
    }
    
    }lct;
    
    std::set<PII> S;
    
    bool link(int i)
    {
    	int u = edge[i].u, v = edge[i].v;
    	int w = edge[i].wb;
    	if (lct.find(u) == lct.find(v)) {
    		PII o = lct.query(u, v);
    		if (o.first <= w) return false;
    		S.erase(o);
    //		fprintf(stderr, "%d
    ", o.second);
    		lct.cut(edge[o.second].u, o.second + N);
    		lct.cut(edge[o.second].v, o.second + N);
    	}
    //	fprintf(stderr, "%d %d edge_id = %d
    ", u, v, cur);
    //	assert(lct.find(u) != lct.find(v));
    	lct.link(u, i + N), lct.link(v, i + N);
    	return true;
    }
    
    bool cut(int i)
    {
    	int a = edge[i].u, b = i + N;
    	lct.make_root(a);
    	lct.access(b);
    	lct.splay(b);
    
    	int sz1 = lct.sz_all[a];
    	int sz0 = lct.sz_all[b] - sz1;
    
    	int tot = ::tot;
    	tot -= lct.sz_all[b] >= K;
    	tot += sz1 >= K;
    	tot += sz0 >= K;
    
    	if (tot) {
    		lct.cut(edge[i].u, i + N);
    		lct.cut(edge[i].v, i + N);
    		return true;
    	}
    
    	return false;
    }
    
    
    int main()
    {
    	freopen("mincost.in", "r", stdin);
    	freopen("mincost.out", "w", stdout);
    
    	N = read(); M = read(), K = read();
    	for (int i = 1; i <= N; ++i) {
    		a[i] = read(), b[i] = read();
    	}
    
    	if (K == 1) {
    		int ans = inf;
    		for (int i = 1; i <= N; ++i) 
    			chkmin(ans, a[i] + b[i]);
    		printf("%d
    ", ans);
    		return 0;
    	}
    
    	for (int i = 1; i <= M; ++i) {
    		int u = read(), v = read();
    		int wa = std::max(a[u], a[v]);
    		int wb = std::max(b[u], b[v]);
    		edge[i] = (Edge) {u, v, wa, wb};
    	}
    
    	std::sort(edge + 1, edge + M + 1);
    
    	int ans = inf;
    	for (int i = 1; i <= M; ++i) {
    //		cur = i;
    		if (link(i)) {
    			S.insert(PII(edge[i].wb, i));
    		}
    //		fprintf(stderr, "%d %d %d
    ", i, edge[i].u, edge[i].v);
    		while (true) {
    			std::set<PII>::iterator it = --S.end();
    			if (cut(it->second)) {
    				S.erase(it);
    			}
    			else break;
    		}
    
    		if (tot) {
    			chkmin(ans, (--S.end())->first + edge[i].wa);
    		}
    	}
    
    	if (ans >= inf) 
    		printf("no solution
    ");
    	else
    		printf("%d
    ", ans);
    //	fprintf(stderr, "%lf
    ", 1.0 * clock()/CLOCKS_PER_SEC);
    
    	return 0;
    }
    
    
  • 相关阅读:
    5、include为应用指定多个struts配置文件
    4、struts处理流程和action的管理方式
    8、类型转换器
    7、请求参数接收
    UESTC 2014 Summer Training #6 Div.2
    Codeforces Round #FF
    css ul li去除圆点
    css a标签去除下划线
    Axure的热区元件的作用
    结组开发项目(TD学生助手)
  • 原文地址:https://www.cnblogs.com/pbvrvnq/p/8763169.html
Copyright © 2011-2022 走看看