T1
真的太巧妙了O(1)做法 其实我不会o(n)做法
首先考虑到 (x=-1,x=0,x=-1) 是三个互不关联的事件 显然(P(x=-1)+P(x=0)+P(x=1)=1) 我们令(a=P(x=-1),b=P(x=0),c=P(x=1)) 所以(a+b+c=1) 题目告诉你$ p_i =ap_{i-1}+bp_i+cp_{i+1}(i =1;2;.....;2n 1)$ 我们移一下项可以得到:((1-b)p_i=ap_{i-1}+cp_{i+1}) 又(1-b=a+c) 因此((a+c)p_i=ap_{i-1}+cp_{i+1}) 移一下项可以得到:(a(p_i-p_{i-1})=c(p_{i+1}-p_i)) (frac {(p_{i+1}-p_i)} {p_{i}-p_{i-1}}=frac {a}{c}) 令其等于(k) 显然(k)表示相邻两个(p)的差值之间的关系 令(d_i=p_i-p_{i-1},d_1=x) 显然(d_{i+1}=d_i*k) 因此可以用等比数列表示(p_{2n}-p_{2n-1}=d_{2n}=x*k^{2n-1}) 再将这些前缀和一下得到:(p_{2n}=x*cdot{1-k^{2n}}{1-k}=1) 则(x=frac{1-k}{1-k^{2n}}) 因此(p_{n}=xcdot frac{1-k^n}{1-k}=frac{1-k}{1-k^{2n}}cdot frac{1-k^n}{1-k}=frac{1-k^n}{1-k^{2n}}) 将(k^n) 看做整体 会惊奇的发现分数线下面是一个平方差公式 然后约分得到(frac{1}{1+k^n}) 又(k=frac {a}{c}) 将(k)带回去就会得到(frac {c^n}{c^n+a^n}) 因为数据随机生成 所以不用担心其没有逆元的情况 然后用逆元就可以了qaq 另外关于如何计算$a,b (显然)a=(1-alpha)cdoteta$, (b=(1-eta)cdotalpha) 因为是在(mod 1e9+7)意义下的 而还有个这样的结论:((1-alpha)\%mod=(1-alpha\%mod+mod)\%mod) 然后就可以了
代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define LL long long
using namespace std;
const LL mod=1e9+7;
LL alph,beta,b,n;
LL a,c,wow;
LL ksm(LL x,LL y){
LL ans=1;
while(y){
if(y&1) ans=ans*x%mod;
x=(x*x)%mod;y>>=1;
}
return ans;
}
int main(){
scanf("%lld %lld %lld",&n,&alph,&beta);
a=((1-alph%mod)+mod)%mod*beta%mod;
c=((1-beta%mod)+mod)%mod*alph%mod;
c=ksm(c,n);a=ksm(a,n);a=(a+c)%mod;
a=ksm(a,mod-2);
printf("%lld",(a%mod*c%mod+mod)%mod);
return 0;
}
T2
一道模拟的水题 注意两点:1. S可能并不会出现在手牌中,离散化之前要将S加入一次离散化队列 2.当游戏只剩下1个人或者0个人的时候就会停止(当前轮数结束时)
吐槽一句,这一道题每一次都操作都(O(n))都能过!(虽然我不是)
另外这道题我数组在调试时开小了调试,最后没改回来都能过数据是真的水QAQ(应该开3e7)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=1100;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,l,s,t,tail;
int lsh[111111],ls,top;
int qaq[maxn][maxn],ed[111111];
vector<int> vec[10010];
queue<int> q[110];
int que[300100],mendes;
int linshi[100010];
int main(){
freopen("fishing.in","r",stdin);
freopen("fishing.out","w",stdout);
while(1){
n=read();m=read();l=read();s=read();t=read();
if(n==-1 && m==-1 && l==-1 && s==-1 && t==-1) break;
top=0;
for(int i=1;i<=n;i++)
for(int j=1,x;j<=l;j++)
x=read(),qaq[i][j]=x,lsh[++top]=x;
lsh[++top]=s;
sort(lsh+1,lsh+1+top);ls=unique(lsh+1,lsh+1+top)-lsh-1;
top=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=l;j++){
q[i].push(lower_bound(lsh+1,lsh+1+ls,qaq[i][j])-lsh);
}
s=lower_bound(lsh+1,lsh+1+ls,s)-lsh;
tail=0;int shawn,fuck;mendes=0;
for(int i=1;i<=t;i++){
if(mendes==n-1 || mendes==n) break;
for(int j=1;j<=n;j++){
if(!q[j].empty()){
if(vec[q[j].front()].size()){
if(q[j].front()==s){
q[j].pop();
if(tail){
for(int k=1;k<=tail;k++)
{
q[j].push(que[k]);
vec[que[k]].pop_back();
}
tail=0;
q[j].push(s);
}
else{
que[++tail]=s;
vec[que[tail]].push_back(tail);
}
}
else{
fuck=q[j].front();q[j].pop();
shawn=vec[fuck].back();
for(int k=vec[fuck].back();k<=tail;k++){
q[j].push(que[k]);
vec[que[k]].pop_back();
}
q[j].push(fuck);tail=shawn-1;
}
}
else if(q[j].front()!=s){
que[++tail]=q[j].front();
vec[q[j].front()].push_back(tail);
// printf("%d
",vec[q[j].front()].back());
q[j].pop();
}
else{
q[j].pop();
if(tail){
for(int k=1;k<=tail;k++)
{
q[j].push(que[k]);
vec[que[k]].pop_back();
}
tail=0;q[j].push(s);
}
else{
que[++tail]=s;
vec[que[tail]].push_back(tail);
}
}
if(q[j].empty()) ed[j]=i,mendes++;
}
}
}
for(int i=1;i<=n;i++){
if(!q[i].empty()) printf("%d ",q[i].size());
else printf("-%d ",ed[i]);
}
printf("
");
for(int i=1;i<=n;i++){
while(!q[i].empty()){
printf("%d ",lsh[q[i].front()]);
q[i].pop();
}
printf("
");
}
for(int i=1;i<=ls;i++)
vec[i].clear();
// memset(que,0,sizeof(que));
}
return 0;
}
T3
这道题可能只能欣赏一下吧QAQ 所以正解就复制一下题解 我讲一下部分分吧QAQ
说是部分分可是 我也只会(50pts)的部分分 (其实这道题我一看就以为是树上莫队,然而突然发现强制在线)
那么这(50pts)的部分分如何拿呢? (其实是因为有(50pts)的数据不强制在线QAQ)
说白了就是。。。。我只会离线算法QAQ
首先你离线下来,然后用树上莫队,用一个桶来存储每个颜色出现的数量,然后(O(n)) 查询最大值
不要给我说什么超时 这道题一个点10s的时限
然而我就不放代码了(其实是没有写)