[考试总结]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();}
posted @ 2021-09-13 20:15  NP2Z  阅读(31)  评论(0编辑  收藏  举报