2023.5.19
T1
已知 \(\gcd(a,b)=G,\text{lcm}(a,b)=L\),求 \(\min\{a+b\}\),无解 \(-1\).
\(1\le T\le 5\),\(1\le G,L\le 10^{12}\).
无解即当 \(G\not|\space L\).
有
枚举 \(\frac{L}{G}\) 的因数再check一下 \(\gcd\) 即可。
我打了一个状压,然后没判 \(G=L\) 爆了 \(40\) 分。
T2
\(n\) 个物品,问共多少种方式,选择若干物品且有 \(\forall i,j\),\(x_ix_j+y_iy_j\not=0\).(不包含空集)
答案对 \(1e9+7\) 取模。
\(1\le n\le 2\times 10^5\),\(-10^{18}\le x_i,y_i\le10^{18}\).
把 \(\frac{x_i}{y_i}\) 化成既约分数的形式存进 \(\rm map\) 里,用一个桶存一存,查询倒数的相反数然后乱搞即可。
-
\(x=y=0\):只能选自己,把答案计入 \(zer\) 里。
-
\(x=0,y\not=0\):可以任选 \(x\not=0,y=0\) 之外的数。
-
\(x\not=0,y=0\):同理。
这两部分的处理方式和其他是一样的。
设两部分的大小为 \(A,B\),那么方案数是 \(2^A+2^B-1\),所有东西乘起来再减去空集 \(1\).
处理 \(0\) 的地方写炸挂了 \(35\) 分。
#include<bits/stdc++.h>
#define ll long long
#define N 200010
#define make make_pair
#define Mod 1000000007
using namespace std;
ll read(){
ll x=0,w=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*w;
}
int n,tot;
ll x[N],y[N],gcd,zer;
vector<int>s[N];
ll cnt[N];bool vis[N];
map<pair<ll,ll>,int>mp;
ll p2[N],ans,cntx,cnty;
int main(){
n=read(),ans=1,p2[0]=1;
for(int i=1,tp;i<=n;i++){
x[i]=read(),y[i]=read();
p2[i]=p2[i-1]*2%Mod;
if(!x[i]&&!y[i]){zer++;continue;}
if(!x[i]){cntx++;continue;}
if(!y[i]){cnty++;continue;}
if(y[i]<0)x[i]*=-1,y[i]*=-1;
gcd=__gcd(abs(x[i]),y[i]),x[i]/=gcd,y[i]/=gcd;
if(!mp[make(x[i],y[i])])mp[make(x[i],y[i])]=++tot;
tp=mp[make(x[i],y[i])],cnt[tp]++,s[tp].push_back(i);
}
for(int i=1,cur,rev;i<=n;i++){
if(vis[i]||!x[i]||!y[i])continue;
cur=mp[make(x[i],y[i])];
rev=mp[x[i]<0?make(y[i],-x[i]):make(-y[i],x[i])];
for(int j=0;j<s[cur].size();j++)
vis[s[cur][j]]=true;
if(!rev){
(ans*=p2[cnt[cur]])%=Mod;
continue;
}
for(int j=0;j<s[rev].size();j++)
vis[s[rev][j]]=true;
(ans*=(p2[cnt[cur]]+p2[cnt[rev]]-1)%Mod)%=Mod;
}
printf("%lld\n",(ans*p2[cntx]%Mod*p2[cnty]%Mod+zer+Mod-1)%Mod);
return 0;
}
T3
本题的平面直角坐标系 \(x\) 向下,\(y\) 向右。
\(n\) 条竖着的线段,\(m\) 横着的,从 \((0,0)\) 出发,能扫到多少面积。答案为 \(\infty\) 输出 INF
.
- \((0,0)\) 不在线段上。
\(1\le n,m\le 10^3\),坐标值的绝对值 \(\le 10^9\).
充分发扬人类智慧可以直接被卡完。
T4
已知 \(l_i\le s_i\le r_i\),求 \(s\) 可能的中位数个数。
\(2\le n\le 2\times 10^5\),\(1\le l_i\le r_i\le 10^9\).
这题怎么是个数学题。
对 \(l,r\) 排序,答案对中位数作差。
这个结论暂时没人给我严谨的证明。
sort(l+1,l+1+n),sort(r+1,r+1+n);
if(n&1)printf("%d\n",r[n/2+1]-l[n/2+1]+1);
else printf("%d\n",r[n/2+1]+r[n/2]-l[n/2+1]-l[n/2]+1);
T5
给一个表格填上 \(\lbrack 0,s\rbrack\) 的数,从左上角走到右下角,满足如下规则:
-
只能向下走或者向右走,不能超出表格。
-
若下邻格子大于右邻格子则向下走,否则向右走。
-
经过的所有格子的价值和恰好为 \(s\).
求所有可能的表格总数 \(\rm mod\space10007\).
\(1\le n,m\le 2500\),\(0\le s\le 100\).
统计一些路径数以及它们的冲突。
怎么写我不知道,反正都是保灵。
\(60+65+33+12+0=170\),有点逆天了。