• 【2021夏纪中游记】2021.7.15模拟赛


    2021.7.15模拟赛

    比赛概括:

    (mathrm{sum}=40+0+30+0)

    本来可以拿 (200),但是因为没审完题。唉。

    T1 彩色圆环:

    原题,详见 【YBTOJ】【国家集训队】彩色圆环

    T2 折射伤害:

    题目大意:

    在一个游戏中有n个英雄,初始时每个英雄受到数值为ai的伤害,每个英雄都有一个技能“折射”,即减少自己受到的伤害,并将这部分伤害分摊给其他人。对于每个折射关系,我们用数对(xi,yi,zi)来表示xi将自己受到伤害去掉zi的比例,将这些伤害转移给yi(xi,yi是整数,zi是实数)。

    求出经过反复折射后最后每个英雄受到的实际总伤害。

    思路:

    求出第 (i) 个英雄收到的总伤害(包括折射收到的)(f(i)),可以发现:

    [f(i)=a_i+sum_{j e i}z_{j,i}f(j) ]

    以此得到增广矩阵:

    [left[egin{array}{lcccr|r} 1&-z_{2,1}&-z_{3,1}&cdots&-z_{n,1}&a_1\ -z_{1,2}&1&-z_{3,2}&cdots&-z_{n,2}&a_2\ -z_{1,3}&-z_{2,3}&1&cdots&-z_{n,3}&a_3\ vdots&vdots&cdots&ddots&vdots&vdots\ end{array} ight]]

    高斯消元求解后,再乘上反弹出去的比例就行了。

    代码:

    const int N = 210;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    int n, m;
    double a[N][N], ref[N];
    
    void Gauss()
    {
    	for (int i = 1; i <= n; i++)
    	{
    		int mxi = i;
    		for (int j = i + 1; j <= n; j++)
    			if(fabs(a[mxi][i]) < fabs(a[j][i])) mxi = j;
    		swap(a[mxi], a[i]);
    		double inv = a[i][i];
    		for (int j = i; j <= n + 1; j++)
    			a[i][j] /= inv;
    		for (int j = i + 1; j <= n; j++)
    		{
    			double inv = a[j][i];
    			for (int k = i + 1; k <= n + 1; k++)
    				a[j][k] -= inv * a[i][k];
    		}
    	}
    	for (int i = n - 1; i; i--)
    		for (int j = i + 1; j <= n; j++)
    			a[i][n + 1] -= a[i][j] * a[j][n + 1];
    }
    
    int main()
    {
    	n = Read();
    	for (int i = 1; i <= n; i++)
    		a[i][i] = 1.0, a[i][n + 1] = Read() * 1.0;
    	m = Read();
    	for (int i = 1; i <= m; i++)
    	{
    		int x = Read(), y = Read(); double z;
    		scanf("%lf", &z);
    		a[y][x] -= z, ref[x] += z;
    	}
    	Gauss();
    	for (int i = 1; i <= n; i++)
    		printf ("%.6f
    ", a[i][n + 1] * (1 - ref[i]));
    	return 0;
    }
    

    T3 鱼跃龙门:

    题目大意:

    给定 (n),找到最小的 (x) 使得 (2n|x(x+1))

    正文:

    我们知道 (2n=p_1^{c_1} imes p_2^{c_2} imescdots imes p_m^{c_m})

    找到其中最大的幂 (p_x^{c_x})。在 ([1,2n]) 内枚举它的倍数然后在相邻数中检测是否 (2n) 的其它幂都能被包含。时间复杂度 (mathcal{O}(Tsqrt{n}mathrm{cnt})),其中 (mathrm{cnt}) 表示 (2n) 的质因数个数,理论上说会被卡,但又好像和标算差不多。

    代码:

    const int N = 1e6 + 10;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    bool vis[N];
    ll pri[N], cnt;
    void Prime()
    {
    	for (int i = 2; i <= N - 10; i++)
    	{
    		if (!vis[i]) pri[++cnt] = i, vis[i] = 1;
    		for (int j = 1; j <= cnt && pri[j] * i <= N - 10; j++)
    		{
    			vis[pri[j] * i] = 1;
    			if (!(i % pri[j])) break;
    		}
    	}
    }
    
    int t;
    ll n;
    ll a[N][2], tot;
    
    ll qpow(ll a, ll b)
    {
    	ll ans = 1;
    	for (; b; a = a * a, b >>= 1)
    		if (b & 1) ans = ans * a;
    	return ans;
    }
    
    int main()
    {
    	Prime();
    	for (t = Read(); t--; )
    	{
    		n = Read(); n *= 2;
    		ll m = n;
    		a[tot = 1][0] = 1, a[tot][1] = 1;
    		for (int i = 1; i <= cnt; i++)
    		{
    			if (m % pri[i]) continue;
    			a[++tot][0] = pri[i];
    			a[tot][1] = 0;
    			for (; !(m % pri[i]); m /= pri[i])
    				a[tot][1]++;
    			if (m == 1) break;
    		}
    		if (m != 1) a[++tot][0] = m, a[tot][1] = 1;
    		for (ll i = 1, val = qpow(a[tot][0], a[tot][1]); i * val <= n; i++)
    		{
    			int flag = 1;
    			for (int j = 1; j < tot; j++)
    			{
    				ll val1 = qpow(a[j][0], a[j][1]);
    				if ((i * val - 1) % val1 && (i * val) % val1) {flag = 0; break;}
    			}
    			if (flag) {printf ("%lld
    ", i * val - 1); break;};
    			flag = 1;
    			for (int j = 1; j < tot; j++)
    			{
    				ll val1 = qpow(a[j][0], a[j][1]);
    				if ((i * val + 1) % val1 && (i * val) % val1) {flag = 0; break;}
    			}
    			if (flag) {printf ("%lld
    ", i * val); break;};
    		}
    	}
    	return 0;
    }
    

    T4 [GDOI2017]凡喵识图:

    题目大意:

    正文:

    傻逼文字游戏题目描述。哈希搞搞就好了,个人感觉本题考验代码实现能力。

    代码:

    const int N = 150010;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    int n;
    ll a[N];
    int b[5], vis[N];
    int nxt[5][N];
    
    map<int, int> hash[5];
    
    int Solve(ll x)
    {
    	int i = 0;
    	for (; x; x -= x & -x, i++)
    		if (i > 3) return 4;
    	return i;
    }
    
    int main()
    {
    	freopen("hashing.in", "r", stdin);
    	freopen("hashing.out", "w", stdout);
    	n = Read();
    	for (int i = 1; i <= n; i++)
    	{
    		a[i] = Read();
    		for (int j = 0; j < 4; j++)
    			b[j] = (a[i] >> j * 16) % (1 << 16);
    		int ans = 0;
    		for (int j = 0; j < 4; j++)
    		{
    			if (hash[j].find(b[j]) != hash[j].end())
    			{
    				nxt[j][i] = hash[j][b[j]];
    				for (int k = nxt[j][i]; k; k = nxt[j][k])
    				{
    					if (vis[k] == i) continue; vis[k] = i;
    					if (Solve (a[i] ^ a[k]) == 3) ans++;
    				}
    			} 
    			hash[j][b[j]] = i;
    		}
    		printf ("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    用学习逃避成长,听新知缓解焦虑
    谈谈“人”和“技能”
    SpringMVC的工作原理
    Spring MVC 处理静态资源文件
    nrpe的安装设置
    Maatkit工具使用&lt;一&gt;之mysql主从数据校验工具
    phpcgi占用cpu100%的一次排障之旅
    nginx支持cgi
    如何查看服务器RAID卡信息的SHELL脚本和命令介绍
    Mysql的一次经典故障
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/15017826.html
Copyright © 2020-2023  润新知