前言
- 比賽連結。
團隊成績,最後打銅,獲得薯片一包(Shadow
沒搶到泡麵),搶了兩個首 A,獲得兩包魔芋爽(Shadow
不愧是“原”神),但是 \(T_A\) 也是 STA_OI 原題,我還做過,可惜 Shadow
說晚了,不然就三包魔芋爽了。
沒錯那個 \(-95\) 又是我貢獻的,和上次襯衫比賽不同的是這次到最後也沒有 A 掉,先是找迴圈節(把陣列存成雜湊壓進去)T 掉了,然後直接輸出答案下界得到 \(78pts\),可惜沒有部分分,到最後沒想出正解。
那個 \(-6\) 是我交錯題了>_<。
A 樹構造
- 簽到題,P10678 『STA - R6』月。
STA_OI 原題,按照度數從大到小排序再挨著連即可,但那題是強化版,還要求直徑最小,這題不需要,但這是一個合法構造方案。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=2e5+10,B=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
int n,fa[N],sum;
struct aa {int du,id;}e[N];
bool cmp(aa a,aa b) {return a.du>b.du;}
signed main()
{
read(n);
for(int i=1;i<=n;i++)
{
read(e[i].du),e[i].id=i;
sum+=e[i].du;
}
if(sum!=2*n-2)
{
puts("-1");
return 0;
}
sort(e+1,e+1+n,cmp);
for(int i=1,j=2;i<=n;)
{
if(e[i].du>0)
{
fa[e[j].id]=e[i].id;
e[i].du--,e[j].du--;
j++;
}
else i++;
}
for(int i=2;i<=n;i++)
if((fa[e[i].id]==0&&i!=1)||e[e[i].id].du!=0)
{
puts("-1");
return 0;
}
for(int i=2;i<=n;i++)
{
write(fa[e[i].id],e[i].id);
puts("");
}
}
B 長途巴士
- 不可做題。
C 你是黃金獎盃
- 不可做題。
D 地主鬥
- 大模擬,不可做題。
E Grouping
- 貌似可做?但是不想做了。
F Pivot
- 同名原題。
發現不論如何操作,滿足 \(a_i-a_j\) 的值恆不變,設 \(d=a_n-a_1\)。
欽定序列為升序排序,若另 \(s=a_i\),則有 \(a_1'=2\times a_i-a_n\)。
對於 \(a_1\ge 0\) 的限制,不放直接求 \(a_1\bmod d\),最後答案為 \(a_n'=a_1'\bmod d+d\)。
由此 \(a_1\equiv a_n\pmod d\),所以有 \(2a_i-a_n\equiv 2(a_i-a_1)\),固有 \(a_1'=a_1+2(a_i-a_1)\),其中 \(a_i-a_1\) 恆不變。
對於一個 \(a_i\),只需另下一次操作不再取 \(a_i\) 為 \(s\) 就不會恢復原來狀態,故 \(a_i\) 可以貢獻任意個 \(2(a_i-a_1)\)。
考慮每個 \(a_i\) 的貢獻,設 \(a_1+x\times 2(a_i-a_1)=rd+c\),\(r\) 為任意倍數,\(c\) 表示最後的 \(a_1'\bmod d\),移項有 \(rd-x\times 2(a_i-a_1)=a_1-c\),根據裴蜀定理,有 \(\gcd(2(a_i-a_1),d)|(a_1-c)\),為使 \(c\) 最小取最大倍數的 \(\gcd(2(a_i-a_1),d)\) 即可。迴圈 \(a_i\) 取最小值,答案初始值為 \(a_n\)。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=2e5+10,B=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
int n,a[N],ans;
signed main()
{
read(n);
for(int i=1;i<=n;i++) read(a[i]);
int d=a[n]-a[1];
ans=a[n];
for(int i=1;i<=n;i++)
{
int s=__gcd(2*(a[i]-a[1]),d);
int x=a[1]/s;
ans=min(ans,a[1]-s*x+d);
}
write(ans);
}
G 11 : 23
- 學長打的遊戲,符合歡樂賽主題了,但我沒做。
H 烙印融合
- 簽到題,單調棧板子,原題一抓一大把,不想說啥了。
I 魔術刻印
- 不可做題。
J persona
- 能發現結論就是簽到題。
發現最後狀態一定可以是連續一段長度為 \(k\) 的連續區間選擇選或不選,其餘的隨便拿,從貪心的角度其餘的只拿正的即可,列舉是哪塊區間即可。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=2e5+10,B=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
ll n,k,a[N],sum[N],s[N],ans=0;
signed main()
{
read(n),read(k);
for(int i=1;i<=n;i++)
{
read(a[i]);
sum[i]=sum[i-1]+(a[i]>0)*a[i];
s[i]=s[i-1]+a[i];
}
for(int i=k;i<=n;i++)
ans=max(ans,max(0ll,s[i]-s[i-k])+sum[i-k]+sum[n]-sum[i]);
write(ans);
}
K 可持久化非確定性有窮狀態決策自動機
- 魔怔題,因為
Shadow
足夠魔怔,我選擇粘他的“題解”。
首先忽略題目背景和名稱。
現在 HZOI 構建了一個自動機,但很巧的是他只能接受一個長度為 8 的字串。
猜測與 HZOI 有關。
他是你們的某位學長的學長的學長的學長......
bobo
說過 huge
是 HZ 畢業的。
他暑假的出場方式是回宿舍整改。
huge
查宿查的最嚴了,feifei
最多算“幫兇”。
表達你對他的愛,答案為 \(8\) 個字元。
所以答案為 woaihuge
。沒做出來的反省一下自己。
L 隨
設 \(f_{i,j}\) 表示當前數為 \(i\),進行了 \(j\) 輪的機率,有 \(f_{i\times j\bmod P,k}+=f_{i,l}\times f_{j,k-l}\)。於是考慮倍增最佳化。
再次設 \(f_{i,j}\) 表示當前數為 \(i\),進行了 \(2^j\) 輪時的機率,有 \(f_{i\times j\bmod P,k}+=f_{i,k-1}\times f_{j,k-1}\),最後對 \(m\) 二進位制拆分統計期望即可。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e5+10,M=1010,P=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
ll n,m,mod,a[N],sum[M],pos[31],s,f[31][M],g[31][M],ans,tot;
ll qpow(ll a,ll b)
{
ll ans=1;
for(;b;b>>=1)
{
if(b&1) (ans*=a)%=P;
(a*=a)%=P;
}
return ans;
}
signed main()
{
read(n,m,mod);
for(int i=1;i<=n;i++) read(a[i]),sum[a[i]]++;
for(int i=0;i<=mod-1;i++) f[0][i]=sum[i]*qpow(n,P-2)%P;
for(int k=1;k<=__lg(m);k++)
for(int i=0;i<=mod-1;i++)
for(int j=0;j<=mod-1;j++)
(f[k][i*j%mod]+=f[k-1][i]*f[k-1][j]%P)%=P;
for(int i=0;i<=__lg(m);i++)
if(m&(1<<i)) pos[++tot]=i;
for(int i=0;i<=mod-1;i++) g[1][i]=f[pos[1]][i];
for(int k=2;k<=tot;k++)
for(int i=0;i<=mod-1;i++)
for(int j=0;j<=mod-1;j++)
(g[k][i*j%mod]+=g[k-1][i]*f[pos[k]][j]%P)%=P;
for(int i=0;i<=mod-1;i++) (ans+=g[tot][i]*i%P)%=P;
write(ans);
}