[考试总结]noip模拟10

不小心有咕掉了一段时间

这次考试咕掉的分数也是太多了

然后就是这次暴力完全没有打满

遗憾啊遗憾

T1

入阵曲

前面的题目背景故意引导我们去往矩阵快速幂的方向去想

然而半毛钱关系没有

其实就是维护前缀和

二维的

然后就有显然的 \(\mathcal O(n^4)\)暴力

然而我这个 \(sb\) 在考试之前认为没有开 \(long\;long\) 的必要,然后就把 \(long \;long\) 给关了。

\(60\;->\;50\)

心态炸裂

\(\huge_{\text{以后我要是在打暴力关long long我就是dogge}}\)

然后正解就是可以压缩一维的计算。

就是对于每个余数进行记录就行。

之后就是一个优秀\(\mathcal O(n^3)\) 的算法。

其实我认为有点扫描线的感觉。

\(code:\)



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define int long long
#define debug cout<<"debug"<<endl
#define freopen eat2 = freopen
#define scanf eat1 = scanf
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
	char buf[1<<20],*p1 = buf,*p2 = buf;FILE *eat2;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile(){freopen("o.txt","w",stdout);}
	inline int get()
	{
		int 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; int eat1;
static const int maxn = 401,maxl = 1e6+10;
#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 a[maxn][maxn];
	int ans;
	int n,m,k;
	int he[maxn][maxn],b[maxl],cnt[maxl];
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get(); m = get(); k = get();
		try(i,1,n) try(j,1,m) 
		{
			a[i][j] = get();
			he[i][j] = he[i-1][j] + he[i][j-1] - he[i-1][j-1] + a[i][j];
		}
//		try(i,1,n){cout<<endl; try(j,1,m) cout<<he[i][j]<<' ';} cout<<endl;
		try(i,0,n-1) try(j,i+1,n)
		{
			cnt[0] = 1;
			try(t,1,m)
			{
				b[t] = (he[i][t] - he[j][t]) % k;
				if(b[t] < 0) b[t] += k;
				ans += cnt[b[t]]++;
			}
			try(t,1,m) cnt[b[t]] = 0;
		}
		cout<<ans<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

码风逐渐扭曲

T2

遗憾的不是没有想出来看似简单的贪心正解。

而是没有打对自己的暴力。

我不是很擅长暴力的嘛

好吧

暴力就是对于每一个答案进行枚举

然后对于这个答案的方案进行暴力的枚举

然后进行 \(check\)

之后发现 \(ok\) 的就可以 \(return \;0\) 了。

然后就可以愉快的 \(50pts\)

其实在 \(k==1\) 的部分可以打一个小胖守皇宫

之后愉快 \(80pts\)

其实正解就是贪心

从深度大的开始枚举

如果这个点没有被守卫到那么就将他的 \(k\) 级祖先安排哨兵

就这?!

就这



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
#define freopen eat2 = freopen
#define scanf eat1 = scanf
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
	char buf[1<<20],*p1 = buf,*p2 = buf;FILE *eat2;
	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; int eat1;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define m(c,num,size) memset(c,num,size)
static const int maxn = 1e6+10;
namespace xin
{
	class xin_edge{public:int next,ver;}edge[maxn];
	class xin_data
	{
		public:
			int bian,d;
			friend bool operator < (xin_data x,xin_data y)
			{return x.d > y.d;}
	}a[maxn];
	int head[maxn],zhi = 0;
	inline void add(int x,int y){edge[++zhi].ver = y; edge[zhi].next = head[x]; head[x] = zhi;}
	int n,k,t;
	int d[maxn];
	bool vis[maxn],s[maxn];
	inline void topo()
	{
		std::queue<signed>q;
		q.push(1); a[1].d = 1; vis[1] = 1; d[1] = 1;
		while(!q.empty())
		{
			register int x = q.front(); q.pop();
			for(register int i=head[x];i;i=edge[i].next)
			{
				register int y = edge[i].ver;
				if(!vis[y])
				{
					vis[y] = 1;
					q.push(y);
					a[y].d = a[x].d + 1;
					d[y] = d[x] + 1;
				}
			}
		}
	}
	bool ok = 0;
	void dfs(int x,int fa,int cnt)
	{
		if(cnt > k) return ;
		if(s[x]) {ok = 1;return;}
		for(register int i=head[x];i;i=edge[i].next)
		{
			register int y = edge[i].ver;
			if(y == fa) continue;
			dfs(y,x,cnt+1);
		}
	}
	void find(int x,int cnt)
	{
		s[x] = 1;
		if(cnt == k or x == 1) {return;}
		for(register int i=head[x];i;i=edge[i].next)
		{
			register int y = edge[i].ver;
			if(d[y] >= d[x]) continue;
//			cout<<"x = "<<x<<" a[x].d = "<<d[x]<<" y = "<<y<<" a[y].d = "<<d[y]<<endl;
			find(y,cnt+1);
		}
	}
	int ans = 0;
	inline void work(int x)
	{
		ok = 0;
		if(s[x]) {ok = 1;}
		else
			dfs(x,-1,0);
		if(!ok)
			s[x] = 1,find(x,0),ans++;
	}
	const int ms = 1e5;
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); k = get<signed>(); t = get<signed>();
		try(i,1,n-1)
		{
			register int x = get<signed>(),y = get<signed>();
			add(x,y); add(y,x);
			a[i].bian = i;
		}
		a[n].bian = n;
		topo();
		std::sort(a+1,a+n+1);
//		try(i,1,n) cout<<a[i].bian<<' '<<a[i].d<<endl;
		try(i,1,n)
			work(a[i].bian);
		cout<<ans<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

T3

我用的背包

然后被某神笨认定假的。

然而不知道为什么我的code过了

既然假了,那就不写了。


这次真的咕了好多啊

posted @ 2021-07-03 10:30  NP2Z  阅读(39)  评论(0编辑  收藏  举报