zoukankan      html  css  js  c++  java
  • NOIP2017 Day2 题解

    A - 奶酪

    直接用并查集维护即可。(本来一个dfs就够了)

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <ctime>
    #include <iostream>
    #include <queue>
    #include <stack>
    #define rep(i, a, b) for(rint (i) = (a), __omega = (b); (i) <= __omega; ++(i))
    #define rint rg int
    #define rg register
    
    namespace work {
    
        int F() {
            rg char ch; rint x, a;
            while(ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
            if(ch == '-') a = -1, ch = getchar(); else a = 1;
            x = ch-'0';
            while(ch = getchar(), ch >= '0' && ch <= '9')
                x = (x<<1)+(x<<3)+ch-'0';
            return x*a;
        }
        
        struct point {
            int x, y, z;
            point(int X = 0, int Y = 0, int Z = 0) : x(X), y(Y), z(Z) { }
            long long dis2() { return 1ll*x*x+1ll*y*y+1ll*z*z; }
            point operator-(rg const point &that) { return point(x-that.x, y-that.y, z-that.z); }
        } p[1010];
        
        int fa[1010], siz[1010];
        
        int find(rint x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
        
        void unit(rint x, rint y) {
            x = find(x), y = find(y);
            if(siz[x] < siz[y]) std::swap(x, y);
            siz[x] += siz[y]; fa[y] = x;
        }
        
        void solve() {
            rint n, h;
            n = F(), h = F();
            rg long long r;
            r = F();
            rep(i, 1, n)
                fa[i] = i, siz[i] = 1, p[i].x = F(), p[i].y = F(), p[i].z = F();
            fa[n+1] = n+1, fa[n+2] = n+2;
            siz[n+1] = siz[n+2] = 1;
            rep(i, 1, n)
                if(p[i].z <= r && p[i].z >= -r)
                    unit(n+1, i);
            rep(i, 1, n)
                if(p[i].z >= h-r && p[i].z <= h+r)
                    unit(n+2, i);
            r = r*r<<2;
            rep(i, 1, n)
                rep(j, i+1, n)
                    if((p[j]-p[i]).dis2() <= r)
                        unit(i, j);
            if(find(n+1) == find(n+2)) puts("Yes");
            else puts("No");
        }
    
        void main() {
            rint test = F();
            while(test--) solve();
        }
    
    }
    
    int main() {
        //freopen("cheese.in", "r", stdin);
        //freopen("cheese.out", "w", stdout);
        work::main();
        return 0;
    }
    

      

    B - 宝藏

    f[i][k][S]表示第i个点深度为k,集合为S的最小值,枚举子集转移即可。

    //waz
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
    
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
    
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
    
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
    
    int n, m;
    
    int f[14][14][1 << 12];
    
    int t[14][14];
    
    int main()
    {
    	gii(n, m);
    	memset(t, -1, sizeof t);
    	for (register int i = 1; i <= m; ++i)
    	{
    		register int a, b, c;
    		giii(a, b, c);
    		if (t[a][b] == -1)
    			t[a][b] = t[b][a] = c;
    		else
    			t[a][b] = t[b][a] = min(t[a][b], c);
    	}
    	memset(f, 63, sizeof f);
    	register int inf = f[0][0][0];
    	for (register int k = n - 1; ~k; --k)
    	{
    		for (register int i = 1; i <= n; ++i)
    			f[k][i][(1 << (i - 1))] = 0;
    		for (register int s = 1; s < (1 << n); ++s)
    		{
    			for (register int i = 1; i <= n; ++i)
    			{
    				if (!(s & (1 << (i - 1)))) continue;
    				for (register int ss = s - 1; ss; ss = (ss - 1) & s)
    				{
    					if (f[k][i][s ^ ss] == inf) continue;
    					for (register int j = 1; j <= n; ++j)
    					{
    						if (!(ss & (1 << (j - 1)))) continue;
    						if (t[i][j] == -1) continue;
    						f[k][i][s] = min(f[k][i][s], f[k + 1][j][ss] + f[k][i][s ^ ss] + (k + 1) * t[i][j]);
    					}
    				}
    			}
    		}
    	}
    	int ans = 1e9;
    	for (register int i = 1; i <= n; ++i)
    		ans = min(ans, f[0][i][(1 << n) - 1]);
    	printf("%d
    ", ans);
    	return 0;
    }
    

      

    C - 列队

    用动态开点线段树维护哪些要被删除,再用平衡树维护新添加的即可。

    //waz
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
    
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
    
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
    
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
    
    const int N = 3e5 + 10;
    
    struct node1
    {
    	int siz;
    	node1 *ls, *rs;
    } tr1[N * 20], *nt1 = tr1, *rt1[N], *nul1;
    
    void ins1(node1 *&o, int l, int r, int x)
    {
    	if (r < x || x < l) return;
    	if (!o) o = ++nt1;
    	++(o -> siz);
    	if (l == r) return; 
    	int mid = (l + r) >> 1;
    	ins1(o -> ls, l, mid, x);
    	ins1(o -> rs, mid + 1, r, x);
    }
    
    int kth1(node1 *&o, int l, int r, int k)
    {
    	if (l == r) return l;
    	int ls = 0, rs = 0;
    	if (o) ls = o -> ls ? o -> ls -> siz : 0, rs = o -> rs ? o -> rs -> siz : 0;
    	int mid = (l + r) >> 1;
    	ls = (mid - l + 1) - ls;
    	rs = (r - mid) - rs;
    	if (k <= ls) return kth1(o ? o -> ls : nul1, l, mid, k);
    	else return kth1(o ? o -> rs : nul1, mid + 1, r, k - ls);
    }
    
    struct node2
    {
    	int64 val;
    	int rnd;
    	int siz;
    	node2 *son[2];
    	node2(int64 v = 0) { val = v, rnd = rand(); siz = 1; son[0] = son[1] = 0; }
    	void push_up()
    	{
    		siz = 1;
    		if (son[0]) siz += son[0] -> siz;
    		if (son[1]) siz += son[1] -> siz;
    	}
    } tr2[N << 2], *rt2[N], *nt2 = tr2;
    
    int siz2(node2 *x) { return x ? x -> siz : 0; }
    
    node2 *merge(node2 *x, node2 *y)
    {
    	if (!x) return y; if (!y) return x;
    	if ((x -> rnd) < (y -> rnd))
    	{
    		x -> son[1] = merge(x -> son[1], y);
    		x -> push_up();
    		return x;
    	}
    	else
    	{
    		y -> son[0] = merge(x, y -> son[0]);
    		y -> push_up();
    		return y;
    	}
    }
    
    pair<node2*, node2*> split(node2 *x, int k)
    {
    	if (!x) return pair<node2*, node2*>(0, 0);
    	pair<node2*, node2*> ret;
    	if (k <= siz2(x -> son[0]))
    	{
    		ret = split(x -> son[0], k);
    		x -> son[0] = ret.se;
    		x -> push_up();
    		ret.se = x;
    		return ret;
    	}
    	else
    	{
    		ret = split(x -> son[1], k - siz2(x -> son[0]) - 1);
    		x -> son[1] = ret.fi;
    		x -> push_up();
    		ret.fi = x;
    		return ret;
    	}
    }
    
    void ins2(node2 *&x, int64 v)
    {
    	node2 *t = ++nt2;
    	*t = node2(v);
    	x = merge(x, t);
    }
    
    int64 del2(node2 *&x, int k)
    {
    	pair<node2*, node2*> A = split(x, k - 1);
    	pair<node2*, node2*> B = split(A.se, 1);
    	x = merge(A.fi, B.se);
    	return (B.fi) -> val;
    }
    
    int siz[N];
    
    int main()
    {
    	srand(time(0));
    	int n, m, q;
    	giii(n, m, q);
    	for (int i = 1; i <= n; ++i)
    		ins2(rt2[0], 1LL * i * m), siz[i] = m - 1;
    	int id = 0; 
    	while (q--)
    	{
    		++id;
    		int x, y;
    		gii(x, y);
    		if (y != m)
    		{
    			if (y <= siz[x])
    			{
    				int v = kth1(rt1[x], 1, m - 1, y);
    				int64 val = (x - 1LL) * m + v;
    				printf("%lld
    ", val);
    				ins1(rt1[x], 1, m - 1, v);
    				int64 cur = del2(rt2[0], x);
    				ins2(rt2[x], cur);
    				ins2(rt2[0], val);
    				--siz[x];
    			}
    			else
    			{
    				int64 val = del2(rt2[x], y - siz[x]);
    				printf("%lld
    ", val);
    				int64 cur = del2(rt2[0], x);
    				ins2(rt2[x], cur);
    				ins2(rt2[0], val);
    			}
    		}
    		else
    		{
    			int64 val = del2(rt2[0], x);
    			ins2(rt2[0], val);
    			printf("%lld
    ", val);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    DOM对象和jQuery对象的区别
    scrollLeft,scrollWidth,clientWidth,offsetWidth详解
    js数组去重
    变量和作用域的小结
    JS练习题之字符串一
    css实现布局
    将字符串或者数字转化成英文格式输出
    css元素居中实现方法
    不同的函数调用模式
    一个apply的实例
  • 原文地址:https://www.cnblogs.com/AnzheWang/p/9638185.html
Copyright © 2011-2022 走看看