1. 程式人生 > 其它 >[考試總結]noip模擬22

[考試總結]noip模擬22

又發現模擬 \(22\) 的總結也咕掉了,現在補上它。。。

似乎又是gg的一場。

以為自己的部分分數打的很全,然而到後面發現自己的樹剖打假了

\(\color{green}{\huge{\text{樹剖打假???}}}\)

好廢啊。。。

然後我的 \(lca\) 就變成了 \(\mathcal O(n)\)向上標記法

罪魁禍首:

然後。。。

然而改成:

然後:

原地爆炸。。。

生氣。。。

然而並沒有什麼用。。

部分分數都打不全。。。還是水平問題。。。

T1:

利用上一場單調指標的思想,然後我們使用:

雙指標 ---搖擺兵

然後就很簡單了。。。



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define int long long
#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++
	char buf[1<<20],*p1 = buf,*p2 = buf; FILE *xinnb1; typedef long long ll;
	void openfile() {xinnb1 = freopen("t.txt","r",stdin);} void outfile() {xinnb1 = 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; static const int maxn = 1e6+10,inf = 0x7f7f7f7f7f7f7f7f;
#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
{
	class xin_data
	{
		private:
			friend bool operator < (xin_data x,xin_data y)
			{
				if(x.b xor y.b) return x.b < y.b;
				if(x.a xor y.a) return x.a < y.a;
				return x.id < y.id;
			}
		public:
			int a,b,id;
	}xa[maxn],xb[maxn];
	inline bool compa(xin_data x,xin_data y)
	{
		if(x.a xor y.a) return x.a < y.a;
		if(x.b xor y.b) return x.b < y.b;
		return x.id < y.id;
	}
	inline bool compb(xin_data x,xin_data y)
	{
		if(x.b xor y.b) return x.b < y.b;
		if(x.a xor y.a) return x.a < y.a;
		return x.id < y.id;
	}
	bool vis[maxn];
	int n,m;
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		int T = get();
		while(T--)
		{
			n = get(); m = get();
			try(i,1,n) 
			{
				xa[i].a = get(); xa[i].b = get();
				xa[i].id = i; xb[i] = xa[i];
			}
			std::sort(xa+1,xa+n+1,compa);
			std::sort(xb+1,xb+n+1,compb);
			try(i,1,m) vis[xa[i].id] = 1;
			register int j = 1;
			while(vis[xb[j].id]) j++;
			register int ans = xa[m+1].a * xb[j].b;
			throw(i,m,1)
			{
				vis[xa[i].id] = false;
				if(xa[i] < xb[j])
					ans = std::max(ans,xa[i].a * xb[j].b);
				else 	
				{
					j ++;
					while(vis[xb[j].id]) j++;
					ans = std::max(xa[i].a * xb[j].b,ans);
				}
			}
			cout<<ans<<endl;
		}
		return 0;
	}
}
signed main() {return xin::main();}

T2:

正解是可持久化線段樹。

然而還沒學。。

然後 \(gg\)

然而強者暴力有一萬分

就是前提是樹剖打對

生氣。。。

直接\(89pts\)



%: pragma GCC optimize("Ofast")
%: pragma GCC optimize("inline")
#include<bits/stdc++.h>
using std::cout; using std::endl;
//#define int long long
#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++
	char buf[1<<20],*p1 = buf,*p2 = buf; FILE *xinnb1; typedef long long ll;
	void openfile() {xinnb1 = freopen("t.txt","r",stdin);} void outfile() {xinnb1 = 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; static const int maxn = 2e5+10,inf = 0x7f7f7f7f;
#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
{
	class xin_edge{public:int next,ver;}edge[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 c[maxn],type,n,q;
	signed top[maxn],fa[maxn],d[maxn],hson[maxn],siz[maxn];
	int p[maxn];
	inline int min(int x,int y) {return (x < y ? x : y);}inline int max(int x,int y) {return (x > y ? x : y);}
	inline bool pan()
	{
		double t = (double)clock();
		if(t >= 2.4 * CLOCKS_PER_SEC) return false;
		return true;
	}
	#define swap(x,y) (x ^= y ^= x ^= y)
	void dfs1(int x,int f)
	{
		fa[x] = f; d[x] = d[f] + 1; siz[x] = 1;
		for(register int i=head[x];i;i=edge[i].next)
		{
			register int y = edge[i].ver;
			if(y == f) continue;
			dfs1(y,x); siz[x] += siz[y];
			if(siz[y] > siz[hson[x]]) hson[x] = y;
		}
	}
	void dfs2(int x,int t)
	{	
		top[x] = t; 
		if(hson[x]) dfs2(hson[x],t);
		for(register int i=head[x];i;i=edge[i].next)
		{
			register int y = edge[i].ver;
			if(y == fa[x] or y == hson[x]) continue;
			dfs2(y,y);
		}
	}
	inline int lca(int x,int y)
	{
		while(top[x] xor top[y])
		{
			if(d[top[x]] < d[top[y]]) swap(x,y);
			x = fa[top[x]];
		}
		if(d[x] > d[y]) swap(x,y);
		return x;
	}
	int ans = inf;
	inline int abs(int x) {return x > 0 ? x : -x;}
	std::bitset<(maxn >> 1)>vis;
	void pa(int x,int goal,int r)
	{
		if(vis[x]) return ;
		vis[x] = 1;
		ans = min(ans,abs(c[x] - r));
		if(x == goal) return;
		pa(fa[x],goal,r);
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get(); q = get(); type = get();
		bool sp1 = 1,sp2 = 1;
		try(i,1,n) 
		{
			c[i] = get();
			if((c[i] xor c[i-1]) and (i - 1)) sp1 = 0;
		}
		try(i,1,n-1)
		{
			register int x = get(),y = get();
			add(x,y); add(y,x);
			if(x + 1 != y) sp2 = 0;
		}
		if(sp2)
		{
			while(q--)
			{
				register int r = get(),k = get(),allca; ans = inf;
				int maxx = -inf,minn = inf;
				try(i,1,k) p[i] = get(),maxx = max(maxx,p[i]),minn = min(minn,p[i]);
				try(i,minn,maxx)
					ans = min(abs(r - c[i]),ans);
				printf("%d\n",ans);
			}
			return 0;
		}
		dfs1(1,0); dfs2(1,1);
		register int pre = 0;
		try(que,1,q)
		{
			register int r = get(),k = get(),allca; ans = inf;
			try(i,1,k) p[i] = get();		
			if(sp1) {printf("%d\n",abs(r - c[1])); continue;}	
			try(i,1,k)
			{
				p[i] = (p[i] - 1 + type * pre) % n + 1;	
				if(i >= 2) allca = lca(p[i],allca);
				else allca = p[1];
			}
			vis = 0;
//			cout<<allca<<endl;
			try(i,1,k)
			{
				register int x = p[i];
				while(!vis[x] and (allca xor x))
				{
					vis[x] = 1;
					ans = min(ans,abs(r - c[x]));
					x = fa[x];
					if(!ans) break;
				}
				if(!pan()) break;
				ans = min(ans,abs(r - c[allca]));
			}
			printf("%d\n",pre = ans);
		}
		return 0;
	}
}
signed main() {return xin::main();}

T3:

我不會告訴你我現在只會30pts大暴力的

歸併排序大暴力,然後 \(30pts\)

生氣



#include<bits/stdc++.h>
using std::cout; using std::endl;
//#define int long long
#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++
	char buf[1<<20],*p1 = buf,*p2 = buf; FILE *xinnb1; typedef long long ll;
	void openfile() {xinnb1 = freopen("t.txt","r",stdin);} void outfile() {xinnb1 = 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; static const int maxn = 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],r[maxn],n,ans = 0,k,p;
	int c[maxn];
	void ms(register int s,register int t)	 
	{    
		register int m,i,j,k;
		if(s==t)  return;    
		m = (s+t) >> 1;	
		ms(s,m); ms(m+1,t); 
		i = s;j = m+1;	k = s;
		while (i<=m and j<=t)
		{  
			if (a[i]<=a[j]){r[k] = a[i];i++;k++; }
			else{r[k] = a[j];j++;k++;ans += j - k;}
		}
		while(i<=m){r[k] = a[i];i++; k++;}
		while(j<=t){r[k] = a[j];j++;k++;}
		for(i=s;i<=t;i++) a[i] = r[i];
	}
	class xin_data
	{
		private:
			friend bool operator < (xin_data x,xin_data y)
			{return (x.f == y.f) ? x.i < y.i : x.f < y.f;}
		public:
			int i,f;
	}d[maxn];
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get(); k = get(); p = get();
		if(n >= 500000) {cout<<1<<' '<<1<<endl; return 0;}
		try(i,1,n) c[i] = get();
		try(x,0,(1<<k)-1)
		{
			try(i,1,n) a[i] = c[i] xor x;
			ans = 0;
			ms(1,n);
			d[x].f = ans; d[x].i = x;
		}
		std::sort(d,d+(1<<k));
		cout<<d[p-1].f<<' '<<d[p-1].i<<endl;
		return 0;
	}
}
signed main() {return xin::main();}