[考试总结]noip模拟20

第五场,再挂分就没了。。

然后就没了。。

考场上一直想方法。

似乎想到了 \(T1\) 正解。

然而几个 \(k\) 的调试信息都让我迷失了自我。

然后有几句啥都没用的语句加在了上面。。

挂分。。。

然后就没有什么时间检查爆搜。

之后打的垃圾爆搜一共只有 \(20pts\)

最后一题不开 \(long\;long\) 爆炸成一分也是我没有想到的。。。

部分分数明明很多,但是却拿不到。

没有什么形容词了。

粗心,鲁莽,菜

玩具:

设计方程进行转移。

先转移概率。

再统计个数。

(懒得打$ \(LaTeX\) 了,粘个图片)

看算法 \(4\) 就行了。



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
#define int long long
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf
	#define freopen eat2 = freopen
	int eat1; FILE *eat2; char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	template<class type>inline type get()
	{
		type s = 0,f = 1; register char ch = gc();
		while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
		while(isdigit(ch))  {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io; static const int maxn = 1e3+10,inf = 1e9+1;
#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)
namespace xin
{
	int n,mod;
	int f1[maxn][maxn],f2[maxn][maxn],f3[maxn][maxn],f4[maxn][maxn];
	int ksm(int x,int y = mod - 2)
	{
		register int ret = 1;
		while(y)
		{
			if(y & 1) ret = ret * x % mod;
			x = x * x % mod; y >>= 1;
		}
		return ret % mod;
	}
	int dfs(int i,int j)
	{
		if(f1[i][j]) return f1[i][j];
		f1[i][j] = (dfs(i-1,j-1) * (j - 1) % mod + f1[i-1][j] * (i - j) % mod) % mod;
		return f1[i][j];
	}
	int dfs2(int i,int j)
	{
		if(f2[i][j]) return f2[i][j];
//		try(i,1,n) f[i][j] = f3[i - 1][j] % mod * f1[i][j] % mod;
		return f2[i][j];
	}
	int ans = 0;
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<int>(); mod = get<int>();
		f1[1][1] = f2[1][0] = 1;  try(i,0,n) f3[0][i] = 1;
//		dfs(n);
		try(i,2,n) try(j,1,i)
	        f1[i][j] = (f1[i-1][j-1] * (j-1) % mod + f1[i-1][j] * (i - j) % mod) * ksm(i) % mod;//,cout<<"i = "<<i<<" j = "<<j<<" dp[i][j] = "<<dp[i][j]<<endl;
//		try(i,2,n) try(j,1,i)
//			cout<<"i = "<<i<<" j = "<<j<<" f1[i][j] = "<<f1[i][j]<<endl;
		try(i,1,n)
		    try(j,0,n)
		    {
		        if(j) f2[i][j] = f3[i-1][j-1] % mod;
//				cout<<"i = "<<i<<" j = "<<j<<" f[i][j] = "<<f[i][j]<<endl;
		       	try(k,1,i) f3[i][j] += f2[k][j] * f3[i - k][j] % mod * f1[i][k] % mod,f3[i][j] %= mod;//;cout<<"i = "<<i<<" k = "<<k<<" f1[i][k] = "<<f1[i][k]<<endl;
		    }
//		try(i,1,n) try(j,0,n) cout<<"i = "<<i<<" j = "<<j<<" f3[i][j] = "<<f3[i][j]<<endl;
		try(i,1,n)
			ans = (ans + (f2[n][i] - f2[n][i-1] + mod) % mod * i % mod ) % mod;
//		try(i,1,n) cout<<"f2[n][i] = "<<f2[n][i]<<" f2[n][i-1] = "<<f2[n][i-1]<<endl;
//		cout<<ans * ksm(n) % mod<<endl;
		cout<<ans % mod<<endl;
		return 0;
	}
}
signed main(){return xin::main();}

y:

首先考虑搜索。

这个题目很良心,搜索给了好多分数。

但是我们并不能无脑爆搜。

我们可以开始枚举每一个状态。

然后开始检查这个状态的正确性。

如果正确 ans++

最后就是答案

然后还有一个很大很大的坑点。

就是我们在发现 \(c=0\) 的点的时候,他整整给了 \(12pts\)

如果直接输出 \(1\),那么这 \(12pts\) 不就直接拿到了吗?

然而并不是这样,题目当中说从 1 点开始出发,但是如果从 1 点出发没有路径该怎么办呢?

所以还要特判这种 毒瘤 的情况。

然后才能拿到这个 \(12pts\)

\(72pts\;code\)



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf
	#define freopen eat2 = freopen
	int eat1; FILE *eat2; char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	template<class type>inline type get()
	{
		type s = 0,f = 1; register char ch = gc();
		while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
		while(isdigit(ch))  {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 0x3f3f3f3f;
#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)
typedef long long ll;
namespace xin
{
	class xin_edge{public:int next,ver,w;}edge[maxn];
	int head[maxn],zhi = 0;
	inline void add(int x,int y,int z) {edge[++zhi].ver = y ; edge[zhi].w = z; edge[zhi].next = head[x]; head[x] = zhi;}
	int n,m,d,ans = 0;
	bool vis[(1 << 20)+1];
	bool sp1 = 1;
	bool ok = 0;
	void dfs(int x,int ms,int st,int num)
	{
		if(ok) return ;
		if(num == ms)
		{
			ok = 1;
			return ;
		}
		for(register int i=head[x];i;i=edge[i].next)
		{
			register int y = edge[i].ver,z = edge[i].w;
			if((((st >> num ) & 1)) == z) dfs(y,ms,st,num+1);
		}
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); m = get<signed>(); d = get<signed>();
		try(i,1,m)
		{
			register int x = get<signed>(),y = get<signed>(),z = get<signed>();
			add(x,y,z); add(y,x,z);
			if(z) sp1 = 0;
		}
		if(sp1) 
		{
			bool ok = 0;
			try(i,1,zhi) if(edge[i].ver == 1) ok = 1;
			cout<<ok<<endl; 
			return 0;
		}
		try(st,0,(1<<d)-1)
		{
			ok = 0;
			dfs(1,d,st,0);
			ans += ok;
		}
		cout<<ans<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

然后正解也是考虑状态压缩。

之后线性递推出解。。



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf
	#define freopen eat2 = freopen
	int eat1; FILE *eat2; char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	template<class type>inline type get()
	{
		type s = 0,f = 1; register char ch = gc();
		while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
		while(isdigit(ch))  {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io; static const int maxn = 110,inf = 0x3f3f3f3f,maxst = (1 << 13) + 1;
#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)
typedef long long ll;
namespace xin
{
	std::bitset<maxn>a[maxn],b[maxn],f1[maxst],f2[maxst];
	int n,m,d,ans = 0;
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); m = get<signed>(); d = get<signed>();
		try(i,1,m)
		{
			register int x = get<signed>(),y = get<signed>(),z = get<signed>();
			z ? a[x][y] = a[y][x] = true : b[x][y] = b[y][x] = true;
		}
		int d1 = d - (d >> 1),d2 = d - d1;
		throw(u,n,1)
		{
			try(i,0,maxst-1) f1[i] = 0;
			f1[1][u] = 1;
			try(x,1,(1 << d1)-1) try(y,1,n)
				if(f1[x][y])
					f1[x << 1] |= a[y],f1[x << 1 | 1] |= b[y];
			try(x,0,(1 << d1) - 1)
				f2[x][u] = f1[1 << d1 | x].any();
		}
		try(i,0,(1 << d1)-1)try(j,0,(1 << d2) - 1)
			if((f1[1<<d2|j] & f2[i]).any())
				++ans;
		cout<<ans<<endl;	
		return 0;
	}
}
signed main() {return xin::main();}

z:

这真是一道毒瘤题目。

到现在没有一人改出。。。

正解是一堆 \(STL\)

然而并不会。。。

贡献一个 \(45pts\) 做法

我们在观察每一个 单调子区间 的时候,只有他的两个端点是有效的。

所以不是端点的删去就行了。

然后愉快\(45pts\)

\(%45\;code\)



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
//#define int long long
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf
	#define freopen eat2 = freopen
	int eat1; FILE *eat2; char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	template<class type>inline type get()
	{
		type s = 0,f = 1; register char ch = gc();
		while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
		while(isdigit(ch))  {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+1;
#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)
typedef long long ll;
namespace xin
{
	int x[maxn],zhi = 0,q[maxn];
	int n,qnum,minn = inf,maxx = -inf;
	bool sp1 = 1;
	inline ll work1(int len)
	{
		register ll l = 0,r = l + len;ll res = 0;
		try(i,1,zhi)
		{
//			cout<<"x[i] = "<<x[i]<<" l = "<<l<<" r = "<<r<<endl;
			if(x[i] > r) 
			{
				res += x[i] - r;
				r = x[i];
				l = r - len;
			}
			if(x[i] < l)
			{
				res += l - x[i];
				l = x[i];
				r = l + len;
			}
		}
		return res;
	}
	inline ll work2(int len)
	{
		register ll l = 0,r = l + len,res = 0;
		try(i,1,n)
		{
			if(q[i] > r)
			{
				res += q[i] - r;
				r = q[i];
				l = r - len;
			}
			if(q[i] < l)
			{
				res += l - q[i];
				l = q[i];
				r = l + len;
			}
		}
		return res;
	}
	bool sp2 = 1;
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); qnum = get<signed>();
		try(i,1,n) q[i] = get<ll>();
		x[++zhi] = q[1];
		try(i,2,n-1)
		{	
			if(q[i] >= q[i-1] and q[i] <= q[i+1]) continue;
			if(q[i] <= q[i-1] and q[i] >= q[i+1]) continue;
			x[++zhi] = q[i];
		}
		x[++zhi] = q[n];
		try(i,1,qnum)
		{
			register int len = get<signed>();
			if(n > 1000)printf("%lld\n",work1(len));
			else printf("%lld\n",work2(len));
		}
		return 0;
	}
}
signed main() {return xin::main();}
posted @ 2021-07-20 11:08  NP2Z  阅读(35)  评论(0编辑  收藏  举报