题面1JZMwl10Z1zyD7QxkSKpRfw evy3
10+20+100
本来能AK的,结果搞成这个鬼样子,真的气啊
如果质因子个数为\(2\)就Bob胜,否则Alice胜,显然。
结论推错了直接100->10。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int main()
{
freopen("game.in","r",stdin),freopen("game.out","w",stdout);
int T,num;LL n,i;
for(scanf("%d",&T);T;--T)
{
scanf("%lld",&n),num=0;
for(i=2;i*i<=n;++i)
if(n==1) break;
else while(!(n%i)) n/=i,++num;
if(n^1) ++num;
puts(num^2? "Alice":"Bob");
}
return 0;
}
我们把鲲降序排序,把视频按\(d\)降序排序。
然后扫鲲,把所有能消灭它的视频放进一个优先队列,优先队列按\(c\)升序排序,然后把堆顶取出计算答案。
若堆空则无解。
\(m\)打成$n$100->20。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1000007;
int a[N];
struct node{int d,c;}t[N];
int operator<(node a,node b){return a.d>b.d;}
int operator>(node a,node b){return a.c>b.c;}
priority_queue<node,vector<node>,greater<node> >q;
int read(){int x=0;char c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
int main()
{
freopen("kun.in","r",stdin),freopen("kun.out","w",stdout);
int n=read(),m=read(),i,top;LL ans=0;
for(i=1;i<=n;++i) a[i]=read();
for(i=1;i<=m;++i) t[i].d=read(),t[i].c=read();
sort(a+1,a+n+1),sort(t+1,t+m+1);
for(i=n,top=1;i;--i)
{
while(t[top].d>=a[i]) q.push(t[top]),++top;
if(!q.empty()) ans+=q.top().c,q.pop();
else return !printf("JiNiTaiMei!");
}
return !printf("%lld",ans);
}
这题的idea非常的妙。
一个显然的结论:我们设红点\(i\)对应蓝点\(p_i\)(排序后),显然\(p_i=i\),否则会有交。
如果没有障碍点,两个点之间的路径数\(num(i,j)=C(x_i-x_j+y_i-y_j,x_i-x_j)\)。(假设\(j\)在\(i\)左上方)
再考虑障碍点,设从红点\(i\)到障碍点\(j\)且途中不经过其他点的方案数\(d_j\),利用容斥,枚举每个在\(i\)和\(j\)组成的矩形中的点(实际上可以直接先按\(y\)再按\(x\)排序,枚举时枚举前面的点,\(x\)坐标大于的话可在计算\(num(i,j)\)的式子中判成\(0\)),\(d_j=num(i,j)-\sum\limits_{k=1}^{j-1}d_knum(k,j)\)。
对于每个红点和障碍点计算出\(d\),那么我们就可以计算出红点\(i\)到蓝点\(j\)的方案书\(f_{i,j}\)。
然后考虑去掉交叉路径的影响,利用容斥,有两条路径相交的要减去,有三条路径相交的要加上...
也就是偶数减去奇数加上,实际上就是\(p\)的逆序对偶数加上奇数减去。
然后我们把这个式子写出来(\(s(p)\)表示\(p\)的逆序对数)\(\sum\limits_p(-1)^{s(p)}\prod_{i=1}^nf_{i,p_i}\)。
可以发现这就是行列式的定义。直接计算即可。
原文:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11519015.html