[考试总结]noip模拟49
Reverse
这就是一个垃圾的 \(bfs\) 然后注意反转的位置不能超过边界!!!
我就是挂在这里了,呜呜呜~~
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &s)
{
register int f = 0;s = 0; register char ch = gc();
while(!isdigit(ch)) {f |= ch == '-'; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
}}io;
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7; const ll llinf = 1e18+7;
namespace xin
{
int n,k,m,s;
bool vis[maxn],arr[maxn];
std::queue<int>q,tim;
int ans[maxn];
inline void work()
{
while(!q.empty()) q.pop(); while(!tim.empty()) tim.pop();
q.push(s); tim.push(0); vis[s] = 1;
while(!q.empty())
{
register int x = q.front(),t = tim.front(); q.pop(); tim.pop();
ans[x] = std::min(ans[x],t);
register int l,r;
if(k < x) l = -k + 1; else l = k - x + 1 - x;
if(x < n - k + 1) r = k - 1; else r = 2 * n - k + 1 - 2 * x;
if(l > r) std::swap(l,r);
for(register int i=l;i<=r;i+=2)
{
register int y = x + i;
if(!i or y > n or y < 1 or vis[y]) continue;
vis[y] = 1;
q.push(y); tim.push(t+1);
}
}
}
inline short main()
{
io >> n >> k >> m >> s;
try(i,1,m)
{
register int x; io >> x;
vis[x] = 1;
}
memset(ans,0x3f,sizeof(ans));
work();
try(i,1,n)
{
if(i == s) printf("0 ");
else if(ans[i] > inf) printf("-1 ");
else printf("%d ",ans[i]);
}
return 0;
}
}
signed main() {return xin::main();}
Silhouette
推一个组合数,发现答案是:
\[f_i = \dbinom{a}{i}(s^i * ((s + )^{a-i}-s^{a-i}))^b\\
Ans = \sum_{i=0}^a(-1)^if(i)
\]
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &s)
{
register int f = 0;s = 0; register char ch = gc();
while(!isdigit(ch)) {f |= ch == '-'; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
}}io;
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7; const ll llinf = 1e18+7;
#define int long long
namespace xin
{
const int mod = 1e9+7;
auto ksm = [](int x,int y) -> int
{
register int ret = 1;
while(y)
{
if(y & 1) ret = ret * x % mod;
x = x * x % mod; y >>= 1;
}
return ret;
};
int x[maxn],y[maxn];
int n;
int ans = 1,fac[maxn],inv[maxn],inv2[maxn];
inline short main()
{
io >> n;
try(i,1,n) io >> x[i]; try(i,1,n) io >> y[i];
fac[0] = fac[1] = inv[0] = inv[1] = inv2[1] = 1;
try(i,2,maxn / 10) fac[i] = fac[i-1] * i % mod,inv2[i] = mod - mod / i * inv2[mod % i] % mod,inv[i] = inv2[i] * inv[i-1] % mod;
auto com = [](int a,int b) -> bool{return a > b;};
std::sort(x+1,x+n+1,com); std::sort(y+1,y+n+1,com);
auto C = [](int n,int m) {return fac[n] * inv[m] % mod * inv[n-m] % mod;};
auto calc = [&](int bian1,int bian2,int a,int b,int s) -> void
{
register int temp = 0;
try(i,0,a)
(temp += ksm(mod-1,i) * C(a,i) % mod * ksm(s,bian2 * i) % mod * ksm(ksm(s + 1,bian1 - i) - ksm(s,bian1 - i)+mod,b) % mod*ksm(s+1,(a-i)*(bian2-b) % (mod - 1)) % mod) %= mod;
(ans *= (temp + mod) % mod) %= mod;
};
int zhi1 = 1,zhi2 = 1;
while(zhi1 <= n or zhi2 <= n)
{
register int num = std::max(x[zhi1],y[zhi2]),cnt1 = 0,cnt2 = 0;
while(zhi1 <= n and x[zhi1] == num) zhi1 ++,cnt1 ++;
while(zhi2 <= n and y[zhi2] == num) zhi2 ++,cnt2 ++;
calc(zhi1 - 1,zhi2 - 1,cnt1,cnt2,num);
}
cout<<ans<<endl;
return 0;
}
}
signed main() {return xin::main();}
seat
dp
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &s)
{
register int f = 0;s = 0; register char ch = gc();
while(!isdigit(ch)) {f |= ch == '-'; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
}}io;
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7; const ll llinf = 1e18+7;
#define int long long
namespace xin
{
int n,mod;
auto ksm = [](int x,int y,int ret = 1) -> int
{
while(y)
{
if(y & 1) ret = ret * x % mod;
x = x * x % mod; y >>= 1;
}
return ret;
};
int dp[maxn/500][maxn/500],f[maxn/500][maxn/500],g[maxn/500][maxn/500];
int vis[maxn],inv[maxn],cnt[maxn],ou[maxn],pos[maxn];
inline short main()
{
io >> n >> mod;
inv[1] = 1; try(i,2,n) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
vis[0] = vis[n+1] = true;
try(i,1,n)
{
int pl = 0,pr = 0,maxx;
try(j,0,n)
{
register int r = j+1;
while(!vis[r]) ++r;
if(r - j > pr - pl) pl = j,pr = r;
j = r - 1;
}
maxx = pr - pl >> 1;
++cnt[maxx]; ou[maxx] += (pr - pl) & 1;
pos[i] = pl + maxx; vis[pl + maxx] = true;
}
register int sum = n;
try(i,1,n)
{
if(!cnt[i]) continue;
int l = sum - cnt[i] + 1,r = sum;
if(i == 1)
try(j,l,r)
try(k,l,r) dp[j][pos[k]]=inv[cnt[i]];
else
{
try(j,0,cnt[i]) try(k,0,ou[i]) f[j][k]=0;
f[0][ou[i]] = 1;
int p = l + ou[i] - 1;
try(j,1,cnt[i])
{
register int kou = 0,kji = 0;
try(k,0,ou[i])
{
if(!f[j-1][k]) continue;
register int jie = (cnt[i] - (j-1)) + k,w = 0;
if(k)
{
w = f[j-1][k] * k * 2 % mod * inv[jie] % mod;
kou = (kou + w * inv[ou[i] * 2]) % mod;
(f[j][k-1] += w) %= mod;
}
if(cnt[i] - ou[i])
{
w = f[j-1][k] * (jie - 2 * k) % mod * inv[jie] % mod;
kji = (kji + w * inv[(cnt[i]+ou[i])-ou[i]*2]) % mod;
(f[j][k] += w) %= mod;
}
}
try(t,l,p) (dp[l+j-1][pos[t]] += kou) %= mod,(dp[l+j-1][pos[t]+1] += kou) %= mod;
try(t,p+1,r) (dp[l+j-1][pos[t]] += kji) %= mod;
// sb(dp[l + j - 1][pos[t]]);
}
try(j,l,p)
{
int nl = pos[j]-i+1,nr = pos[j]+i;
try(k,nl,nr)
{
if(k == pos[j]) continue;
try(t,r+1,n)
{
int s = k < pos[j] ? k + i + 1 : k - i,w = dp[t][k] * inv[2] % mod;
(g[t][k] += w) %= mod; (g[t][s] += w) %= mod;
}
}
try(k,nl,nr) try(t,r+1,n) dp[t][k] = g[t][k],g[t][k] = 0;
}
}
sum -= cnt[i];
}
try(i,1,n) {try(j,1,n) printf("%lld ",dp[i][j]);putchar('\n');}
return 0;
}
}
signed main() {return xin::main();}