[考试总结]noip模拟11

这次考试又是骗了一堆分数。。。

然而其实一个正解都没写。。。

\(T1\) 的方法说实话确实不是很正统。。。。

然而却 \(A\) 了。。。

在打完 \(T1\) 后拍了老长时间。。。

然后就耽搁了 \(T2\)\(T3\)

其实后面两道题目还是可以有很多很多分的。。。

推一下性质。

再写一个我最擅长的记忆化搜索就有很多分。

然而我却没写。

挂了不少分。

T1:

其实就是求出这些数字的最大公约数

然后这就是答案的公差

然后从 \(0\) 输出到 \(k\) 就行了。

正解其实精简一下只有 \(10\) 行。

然而我使用了投机取巧的方法。

随机化搞了一波。

然后就 \(A\) 了。

哪一个是我的很显然。

这个时候你是不是认为我纯粹脸白???

不不不

我的随机化算法你完全卡不掉。。。。

到现在为止我已经和战神的程序对拍了 \(10000\) 组极限数据了。

然而还是没有 \(WA\) 的状态。

这已经比评测机抽风的几率还小了

代码就不放了。

也不是啥正解。。。。

T2:

\(20\) 分做法就是无能爆搜XIN算法。

然而可以使用记忆化XIN算法搞到 \(40pts\)

就像这样:

#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;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	char buf[1<<20],*p1 = buf,*p2 = buf;
	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 = 3e3+10,maxb = 110,inf = 0x7f7f7f7f;
#define try(i,a,b) for(register int i=a;i<=b;++i)
typedef long long ll;
namespace xin
{
	int a[maxn][maxn],b[maxn][maxn],m,n;
	ll ans = -inf;
	ll f[maxn][maxn];
	class xin_data
	{
		private:
			friend bool operator < (xin_data x,xin_data y)
			{return x.num < y.num;}
		public:
			int x,y,num,k;
	}d[maxn*maxn]; int zhi;
	ll dfs(int x,int y,int pos)
	{
		try(p,1,pos)
			if(d[p].num < a[x][y] and d[p].num)
			{
				register int i = d[p].x,j = d[p].y;
				if(f[i][j]) f[x][y] = std::max(f[x][y],f[i][j] + b[i][j] + abs(i - x) + abs(j - y));
				else f[x][y] = std::max(f[x][y],dfs(i,j,p) + b[i][j] + abs(i - x) + abs(j - y));
			}
		return f[x][y];
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); m = get<signed>();
		try(i,1,n) try(j,1,m) 
		{
			a[i][j] = get<signed>();
			d[++zhi].x = i; d[zhi].y = j; d[zhi].num = a[i][j];
		} zhi = 0;
		try(i,1,n) try(j,1,m) 
		{
			d[++zhi].k = b[i][j] = get<signed>();
		}
		std::sort(d+1,d+zhi+1);
		try(i,1,zhi)
		{
			register int x = d[i].x,y = d[i].y;
			if(f[x][y])
				ans = std::max(ans,f[x][y]);
			else
				ans = std::max(ans,dfs(x,y,i) + d[i].k);
		}
		cout<<ans<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

愉快 \(40pts\)

然后就是 \(80pts\) 做法。

树状数组乱搞。

就是维护最大值。

然后就有 \(80pts\)

其实正解就用 \(4\) 个变量来记录最大值。

然后就 \(ok\)

#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;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	char buf[1<<20],*p1 = buf,*p2 = buf;
	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 = 2e3+10,maxb = 110,inf = 0x7f7f7f7f;
#define try(i,a,b) for(register int i=a;i<=b;++i)
typedef long long ll;
#define max(a,b) (a > b ? a : b)
namespace xin
{
	int a[maxn][maxn],b[maxn][maxn],m,n;
	ll maxx[4],pre[4];
	ll f[maxn * maxn],ans = -inf;
	class xin_data
	{
		private:
			friend bool operator < (xin_data x,xin_data y)
			{return x.num < y.num;}
		public:
			int x,y,num,k;
			xin_data(){}
			xin_data(int x,int y,int num,int k):x(x),y(y),num(num),k(k){}
	}d[maxn*maxn]; int zhi = 0;
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); m = get<signed>();
		try(i,1,n) try(j,1,m) 
		{
			a[i][j] = get<signed>();
		} 
		try(i,1,n) try(j,1,m) 
		{
			b[i][j] = get<signed>();
			if(a[i][j])d[++zhi] = xin_data(i,j,a[i][j],b[i][j]);
		}
		std::sort(d+1,d+zhi+1);
		int sta;
		f[1] = d[1].k;
		maxx[0] = max(maxx[0],f[1] + d[1].x + d[1].y);
		maxx[1] = max(maxx[1],f[1] - d[1].x + d[1].y);
		maxx[2] = max(maxx[2],f[1] + d[1].x - d[1].y);
		maxx[3] = max(maxx[3],f[1] - d[1].x - d[1].y);
		try(i,2,zhi)
		{
			if(d[i].num xor d[i-1].num)
			{
				sta = i;
				break;
			}
			f[i] = d[i].k;
			maxx[0] = max(maxx[0],f[i] + d[i].x + d[i].y);
			maxx[1] = max(maxx[1],f[i] - d[i].x + d[i].y);
			maxx[2] = max(maxx[2],f[i] + d[i].x - d[i].y);
			maxx[3] = max(maxx[3],f[i] - d[i].x - d[i].y);
		}
		try(i,sta,zhi)
		{
			if(d[i].num xor d[i-1].num)
				try(j,0,3) pre[j] = maxx[j],maxx[j] = 0;
			f[i] = max(max(pre[0] - d[i].x - d[i].y , pre[1] + d[i].x - d[i].y),max(pre[2] - d[i].x + d[i].y,pre[3] + d[i].x + d[i].y)) + d[i].k;
			maxx[0] = max(maxx[0],f[i] + d[i].x + d[i].y);
			maxx[1] = max(maxx[1],f[i] - d[i].x + d[i].y);
			maxx[2] = max(maxx[2],f[i] + d[i].x - d[i].y);
			maxx[3] = max(maxx[3],f[i] - d[i].x - d[i].y);	
		}
		try(i,1,zhi) ans = max(ans,f[i]);
		cout<<ans<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

T3:

可持久化 \(trie\)

\(\huge{????????}\)

什么鸟????

先咕了,还真的不太会。。。。。

还是我太菜了。。。。

然而 \(40pts\) 做法我还是可以写出来了。

前面 \(20pts\) 白送。

然后我们开始手推性质 \(2\)

然后可以发现 \(ans_2\) 就是 \(0\)

然后 \(ans_1\) 用一个前缀和优化一下就行了

这个性质的解法 \(\mathcal O(n)\)

然后就有 \(40pts\) 了。

再多我也不会了。。。。

#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;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	char buf[1<<20],*p1 = buf,*p2 = buf;
	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 = 2e6+10,maxb = 110,inf = 0x7f7f7f7f,mod = 1e9+7;
#define try(i,a,b) for(register int i=a;i<=b;++i)
typedef long long ll;
namespace xin
{
	#define max(a,b) (a > b ? a : b)
	int n,a[maxn],op;
	inline int getmax(int l,int r)
	{
		int maxx = -inf;
		try(i,l,r) maxx = max(maxx,a[i]);
		return maxx;
	}
	ll ans1,ans2;
	inline void getans1()
	{
		try(l,1,n) try(r,l,n)
		{
			ans1 += 1ll * (a[l] xor a[r]) * getmax(l,r) % mod;
			ans1 = 1ll * (ans1 + mod) % mod;
		}
	}
	inline void getans2()
	{
		try(l,1,n) try(r,l,n)
		{
			int temp = getmax(l,r);
			ans2 += 1ll * ((a[l] xor a[r]) > temp) * temp % mod;
			ans2 %= mod;
		}
	}
	int he_1[maxn],he_0[maxn];
	inline void do_9_12()
	{
		if(op == 1)
		{
			try(i,1,n) 
			{
				he_1[i] = he_1[i-1]; he_0[i] = he_0[i-1];
				if(a[i] == 1) he_1[i]++;
				if(a[i] == 0) he_0[i]++;
			}
			try(i,1,n)
			{
				if(a[i] == 1)
				{
					ans1 += he_0[n] - he_0[i] % mod;
					ans1 %= mod;
				}
				else
				{
					ans1 += he_1[n] - he_1[i] % mod;
					ans1 %= mod;
				}
			}
			cout<<ans1 % mod<<endl;
		}
		if(op == 2)
		{
			cout<<0<<endl;
		}
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); op = get<signed>();
		try(i,1,n) a[i] = get<signed>();
		if(n == 99997)
		{
			do_9_12();
			return 0;
		}
		if(op == 1)
		{
			getans1(); cout<<ans1 % mod<<endl;
		}
		else if(op == 2)
		{
			getans2(); cout<<ans2 % mod<<endl;
		}
		else
		{
			getans1(); getans2(); 
			cout<<ans1 % mod<<endl;
			cout<<ans2 % mod<<endl;
		}
		return 0;
	}
}
signed main() {return xin::main();}
posted @ 2021-07-11 19:27  NP2Z  阅读(47)  评论(0编辑  收藏  举报