20190228

 

T1

Alice和Bob又双叒叕开始玩游戏了。
有一个包含 NNN 个正整数的序列,序列元素不大于 NNN 。紧接着,他们维护了一个可重集合 SSS ,包含序列中的前 PPP 个元素。Alice先手,二人轮流进行下面的一系列操作:
1)从集合 SSS 中拿走一个元素,加到玩家的总分上面;
2)将序列中的下一个数字(如果存在)添加到集合 SSS 中;
这意味着游戏开始时,当第一个数从集合 SSS 中取出后,将序列的第 P+1P+1P+1 项加入到集合 SSS 中,以此类推至集合 SSS 被取空为止。
假使二人都尽力使自己的总分最大,设游戏的结果为Alice的总分与Bob的总分之差,那么请你在给定序列和集合元素的情况下,输出游戏的结果。

题解

我们可以想到一个暴力,用堆维护集合中的数,每次取堆顶
可惜这样效率是 O(nklogn)O(nklogn)O(nklogn) 的,想想怎么优化使得效率变为 O(nk)O(nk)O(nk)
我们可以得到一开始的时候集合内的最大值 maxmaxmax ,然后设一个计数器记录每个数出现了多少次
然后再设刚放进来的数为 nownownow ,那如果 nownownow000 的话我们可以取 maxmaxmax 并且扫计数器找出下一个 maxmaxmax
如果 nownownow 不为 000 的话取出 nownownow
然后更新 nownownow 的话只需要把要放进来的数和 maxmaxmax 作比较就好了, &lt;max&lt;max<max 则清为 000
最后扫一遍计数器取出就可以了

T2

九条可怜在玩一个很好玩的策略游戏:Slay the Spire,一开始九条可怜的卡组里有 2n2n2n 张牌,每张牌上都写着一个数字 wiw_iwi ,一共有两种类型的牌,每种类型各 nnn 张:
攻击牌:打出后对对方造成等于牌上的数字的伤害。
强化牌:打出后,假设该强化牌上的数字为 xxx ,则其他剩下的攻击牌的数字都会乘上 xxx 。保证强化牌上的数字都大于 111
现在九条可怜会等概率随机从卡组中抽出 mmm 张牌,由于费用限制,九条可怜最多打出 kkk 张牌,假设九条可怜永远都会采取能造成最多伤害的策略,求她期望造成多少伤害。
假设答案为 ansansans ,你只需要输出(ans×(2n)!m!(2n−m)!)&VeryThinSpace;mod&VeryThinSpace;998244353(ans \times \frac{(2n)!}{m!(2n-m)!} ) \bmod 998244353(ans×m!(2nm)!(2n)!)mod998244353即可

题解

挺有趣的一道题
不难发现我们要尽量选择强化牌,因为强化牌上的数 &gt;1&gt;1>1
比如假设 a&lt;ba&lt;ba<b ,那么 a+b&lt;a×2a+b&lt;a \times 2a+b<a×2
而且我们肯定选择更大的数
所以我们现将强化牌和攻击牌排序
fi,jf_{i,j}fi,j 表示打出i张强化牌,最后一张是原序列中的第 jjj 张的积的和
gi,jg_{i,j}gi,j 表示打出i张攻击牌,最后一张是原序列中的第 jjj 张的和的和
可以得到转移式子:
fi,j=wj×∑k=1j−1fi−1,kf_{i,j}=w_j \times \sum_{k=1}^{j-1} f_{i-1,k}fi,j=wj×k=1j1fi1,k
gi,j=wj×Cj−1i−1+∑k=1j−1gi−1,kg_{i,j}=w_j \times C_{j-1}^{i-1} + \sum_{k=1}^{j-1} g_{i-1,k}gi,j=wj×Cj1i1+k=1j1gi1,k
Fi,jF_{i,j}Fi,j 表示选出i张强化牌,最优地打出j张牌的贡献
Gi,jG_{i,j}Gi,j 表示选出i张攻击牌,最优地打出j张牌的贡献
Fi,j=∑k=1nfj,k×Cn−ki−jF_{i,j}=\sum_{k=1}^n f_{j,k} \times C_{n-k}^{i-j}Fi,j=k=1nfj,k×Cnkij
Gi,j=∑k=1ngj,k×Cn−ki−jG_{i,j}=\sum_{k=1}^n g_{j,k} \times C_{n-k}^{i-j}Gi,j=k=1ngj,k×Cnkij
最终答案为 ∑i=0m−1Fi,min(i,k−1)∗Gm−i,max(k−i,1)\sum_{i=0}^{m-1} F_{i,min(i,k-1)}*G_{m-i,max(k-i,1)}i=0m1Fi,min(i,k1)Gmi,max(ki,1)
效率 O(Tn2)O(Tn^2)O(Tn2)

T3

时光匆匆,转眼间又是一年省选季……
这是小 Q 同学第二次参加省队选拔赛。今年,小 Q 痛定思痛,不再冒险偷取试题,而是通过练习旧试题提升个人实力。可是旧试题太多了,小 Q 没日没夜地做题,却看不到前方的光明在哪里。
一天,因做题过度而疲惫入睡的小 Q 梦到自己在考场上遇到了一道好像做过的题目,却怎么也想不起曾经自己是怎么解决它的,直到醒来还心有余悸。
小 Q 眉头一皱,感觉事情不妙,于是他找到了你,希望你能教他解决这道题目。小 Q 依稀记得题目要计算如下表达式的值
(∑i=1A∑j=1B∑k=1Cd(ijk))&VeryThinSpace;mod&VeryThinSpace;(109+7)\Big(\sum_{i = 1}^{A}\sum_{j = 1}^{B}\sum_{k = 1}^{C} d(i j k) \Big) \bmod (10^9 + 7)(i=1Aj=1Bk=1Cd(ijk))mod(109+7)
其中 d(ijk)d(i j k)d(ijk) 表示 i×j×ki\times j\times ki×j×k 的约数个数。

题解

先化式子(太难了
∑i=1A∑j=1B∑k=1C∑x∣i∑y∣j∑z∣k[gcd⁡(x,y)=1][gcd⁡(x,z)=1][gcd⁡(y,z)=1]\sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^C\sum_{x|i}\sum_{y|j}\sum_{z|k}[\gcd(x,y)=1][\gcd(x,z)=1][\gcd(y,z)=1]i=1Aj=1Bk=1Cxiyjzk[gcd(x,y)=1][gcd(x,z)=1][gcd(y,z)=1]
∑x=1A∑y=1B∑z=1C[gcd⁡(x,y)=1][gcd⁡(x,z)=1][gcd⁡(y,z)=1]⌊Ax⌋⌊By⌋⌊Cz⌋\sum_{x=1}^A\sum_{y=1}^B\sum_{z=1}^C[\gcd(x,y)=1][\gcd(x,z)=1][\gcd(y,z)=1]⌊\frac{A}{x}⌋⌊\frac{B}{y}⌋⌊\frac{C}{z}⌋x=1Ay=1Bz=1C[gcd(x,y)=1][gcd(x,z)=1][gcd(y,z)=1]xAyBzC
∑x=1A∑y=1B∑z=1C∑i∣x,i∣yμ(i)∑j∣x,j∣zμ(j)∑k∣y,k∣zμ(k)⌊Ax⌋⌊By⌋⌊Cz⌋\sum_{x=1}^A\sum_{y=1}^B\sum_{z=1}^C\sum_{i|x,i|y}\mu(i)\sum_{j|x,j|z}\mu(j)\sum_{k|y,k|z}\mu(k)⌊\frac{A}{x}⌋⌊\frac{B}{y}⌋⌊\frac{C}{z}⌋x=1Ay=1Bz=1Cix,iyμ(i)jx,jzμ(j)ky,kzμ(k)xAyBzC
∑i=1A∑j=1B∑k=1Cμ(i)μ(j)μ(k)∑i∣x,j∣x⌊Ax⌋∑i∣y,k∣y⌊By⌋∑j∣z,k∣z⌊Cz⌋\sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^C\mu(i)\mu(j)\mu(k)\sum_{i|x,j|x}⌊\frac{A}{x}⌋\sum_{i|y,k|y}⌊\frac{B}{y}⌋\sum_{j|z,k|z}⌊\frac{C}{z}⌋i=1Aj=1Bk=1Cμ(i)μ(j)μ(k)ix,jxxAiy,kyyBjz,kzzC
对于下去整的东西我们可以 O(nlogn)O(nlogn)O(nlogn) 进行预处理
fA(i)=∑i∣d⌊Ad⌋f_A(i)=\sum_{i|d}⌊\frac{A}{d}⌋fA(i)=iddA ( B,CB,CB,C 同理
我们考虑如何计算答案
可以发现我们考虑枚举两个数,如果它们的 lcm≤max(a,b,c)lcm \leq max(a,b,c)lcmmax(a,b,c) 则相互连边,则对答案有贡献的就是图中的三元环了(考虑优化
先单独计算三个数相同的情况和三个数中有两个相同的情况
然后后者再两两连边,找出图中的三元环,然后计算答案
献上代码(参考了下网上别的题解

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e5+5,P=1e9+7;
LL ans,fa[N],fb[N],fc[N];
int T,p[N],mu[N],tp,A,B,C,ce,sa[N];
int sb[N],sc[N],d[N],n;bool vis[N];
struct E{int u,v,w;}e[N<<4];
vector<pair<int,int> >g[N];
int main(){
	mu[1]=1;for (int i=2;i<N;i++){
		if (!vis[i]) p[++tp]=i,mu[i]=-1;
		for (int j=1;j<=tp && p[j]*i<N;j++){
			vis[p[j]*i]=1;
			if (i%p[j]) mu[p[j]*i]=-mu[i];
			else break;
		}
	}
	for (scanf("%d",&T);T--;){
		scanf("%d%d%d",&A,&B,&C);n=max(max(A,B),C);
		for (int i=1;i<=n;i++)
			for (int j=i;j<=n;j+=i)
				fa[i]+=A/j,fb[i]+=B/j,fc[i]+=C/j;
//		calc fd(y)=sigma_y|x d/x
		for (int i=1;i<=n;i++) if (mu[i])
			ans+=mu[i]*mu[i]*mu[i]*fa[i]*fb[i]*fc[i];
//		calc three same
		for (int i=1;i<=n;i++) for (int j=1;i*j<=n;j++)
		if (mu[i*j]) for (int k=j+1;1ll*i*j*k<=n;k++)
			if (mu[i*k] && __gcd(j,k)==1){
				int x=i*j,y=i*k,z=x*k;d[x]++;d[y]++;e[++ce]=(E){x,y,z};
				ans+=mu[x]*mu[x]*mu[y]*(fa[x]*fb[z]*fc[z]+fa[z]*fb[x]*fc[z]+fa[z]*fb[z]*fc[x]);
				ans+=mu[x]*mu[y]*mu[y]*(fa[y]*fb[z]*fc[z]+fa[z]*fb[y]*fc[z]+fa[z]*fb[z]*fc[y]);
			}
//		calc two same and link
#define u e[i].u
#define v e[i].v
		for (int i=1;i<=ce;i++){
			if (d[u]>d[v] || (d[u]==d[v] && u>v))
				swap(u,v);g[u].push_back(make_pair(v,e[i].w));
		}
#define F first
#define S second
		for (int i=1;i<=n;i++){
			for (int j=g[i].size()-1;~j;j--){
				int x=g[i][j].F,y=g[i][j].S;
				sa[x]=fa[y];sb[x]=fb[y];sc[x]=fc[y];
			}
			for (int j=g[i].size()-1;~j;j--){
				int x=g[i][j].F,y=g[i][j].S;
				for (int k=g[x].size()-1;~k;k--){
					int a=g[x][k].F,b=g[x][k].S,t=mu[i]*mu[x]*mu[a];
					ans+=t*fa[y]*fb[b]*sc[a];ans+=t*fa[y]*sb[a]*fc[b];
					ans+=t*sa[a]*fb[y]*fc[b];ans+=t*fa[b]*fb[y]*sc[a];
					ans+=t*sa[a]*fb[b]*fc[y];ans+=t*fa[b]*sb[a]*fc[y];
					
				}
			}
#define y g[i][j].F
			for (int j=g[i].size()-1;~j;j--) sa[y]=sb[y]=sc[y]=0;
		}
        printf("%lld\n",ans%P);ans=ce=0;
        for (int i=1;i<=n;i++) d[i]=fa[i]=fb[i]=fc[i]=0,g[i].clear();
	}
	return 0;
}
posted @ 2019-03-02 20:41  xjqxjq  阅读(278)  评论(0编辑  收藏  举报