A 鏡的綺想 (mirror)
籤籤籤。
配對的點對一定 \(x\) 相同,那用 \(O(nm)\) 地匹配一下,因為有幾個點的 \(x\) 全都相同,所以 \(map\) 和 \(umap\) 會塞到 \(n\times m\) 個數,顯然會爆炸,只能開桶,手動把縱座標搞成全正的,就行。
點選檢視程式碼
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=5e3+3,M=4e6+6;
struct node{
int x,y;
int now;
}a[N],c[N];
int b[N<<1];
int cnt;
int mp[M];
int add=1e6;
signed main()
{
freopen("mirror.in","r",stdin);
freopen("mirror.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
a[i].y+=add;
}
for(int i=1;i<=m;i++)
{
cin>>c[i].x>>c[i].y;
c[i].y+=add;
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i].x==c[j].x)
{
mp[(a[i].y+c[j].y)]++;
ans=max(ans,mp[(a[i].y+c[j].y)]);
}
}
}
cout<<ans;
}
B 萬物有靈 (animism)
貪心的考慮,從最底層往上走一定是最大的,然後發現,每一個 \(k\) 層的節點數之和是上一層的 \(\prod a_i\) 倍,因為 \(k\) 是奇數的情況會每層選的不同,於是可以果斷把 \(k\) 乘 \(2\),就是偶數了。
然後發現每一個整段是等比數列,用 \(\log\) 複雜度的求和方式算就行了,因為模數有可能是合數,不能算逆元。
點選檢視程式碼
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k,mod;
const int N=1e6+5;
int a[N],sum[N],ans;
int ppow(int a,int b)
{
int res=1;
while(b)
{
if(b&1) res=(res*a)%mod;
a=(a*a)%mod,b>>=1;
}return res;
}
int f(int now,int d)
{
if(d==1) return now;
if(d==0) return 1;
if(d%2==0) return (f(now,d/2)*(1+ppow(now,d/2))%mod)%mod;
else return (ppow(now,d)+(((1+ppow(now,(d-1)/2))%mod)%mod*f(now,(d-1)/2)%mod)%mod)%mod;
}
signed main()
{
freopen("animism.in","r",stdin);
freopen("animism.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>k>>mod;
for(int i=0;i<k;i++) cin>>a[i];
if(n<N)
{
sum[0]=1;
for(int i=0;i<n;i++) sum[i+1]=sum[i]*a[i%k]%mod;
for(int i=n;i>=0;i-=2) ans=(ans+sum[i])%mod;
return cout<<ans,0;
}
sum[0]=1;
for(int i=1;i<=k*2;i++) sum[i]=(sum[i-1]*a[(i-1)%k])%mod;
if(n<=k*2)
{
for(int i=n;i>=0;i-=2) ans=(ans+sum[i])%mod;
return cout<<ans,0;
}
int rd=n/(k*2);
int S=sum[k*2];
if(n%2==1)
{
int res=0;
for(int i=1;i<=k*2;i+=2) res=(res+sum[i])%mod;
int ret=f(S,rd-1)%mod;ret++;
ans=(ans+res*ret%mod)%mod;
int pp=ppow(S,rd);
for(int i=n%(k*2);i>=1;i-=2) ans=(ans+sum[i]*pp%mod)%mod;
ans=(ans%mod+mod)%mod;
cout<<ans;
}
else
{
int res=0;
for(int i=2;i<=k*2;i+=2) res=(res+sum[i])%mod;
int ret=f(S,rd-1)%mod;ret++;
ans=(ans+res*ret%mod)%mod;
int pp=ppow(S,rd);
for(int i=n%(k*2);i>=1;i-=2) ans=(ans+sum[i]*pp%mod)%mod;
++ans;
ans=(ans%mod+mod)%mod;
cout<<ans;
}
}
C 白石溪 (creek)
\(n^2\) 的 dp 是簡單的。設 dp_{i,j}$ 表示考慮到 \(i\) 位置,前面有 \(j\) 個紅色(或藍色),轉移容易。