[考试总结]noip模拟9

因为某些原因,咕掉了一段时间

所以现在才更新

T1

斐波那契

一看就是规律

然而我选择了暴力

其实完全可以打表去找规律。

然后就可以发现父亲的顺序也是斐波那契

就这

#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 = 61;
namespace xin
{
	int f[maxn],st[maxn];
	std::map < int,bool > vis;
/*	void biao(int x)
	{
		vis[x] = 1;
		if(x <= 0) return ;
		if(x == 2) {vis[x] = 1;  return ;}
		if(x == 1) {vis[x] = 1;  return ;}
		int l = 1,r = 60;
		while(l < r and l != r- 1)
		{
			register int mid = l + r >> 1;
			if(x - st[mid] < 0) r = mid;
			else l = mid;
		}
		biao(x - st[((l + r)>>1)] + 1);
	}*/
	int ans;
/*	void find(int x)
	{
		if(vis[x]) {ans = x; return ;}
		if(x == 2) {find(1); return ;}
		if(x == 1) {ans = 1; return ;}
		int l = 1,r = 60;
		while(l < r and l != r- 1)
		{
			register int mid = l + r >> 1;
			if(x - st[mid] < 0) r = mid;
			else l = mid;
		}
		find(x - st[((l + r) >> 1)] + 1);
	}*/
	void search(int x,int y)
	{
		if(x == y) {ans = x; return ;}
		if(x > y)
		{
			if(x == 2) {search(1,y); return ;}
			if(x == 1) {ans = 1; return;}
			int l = 1,r = 60;
			while(l < r and l != r - 1)
			{
				register int mid = l + r >> 1;
				if(x - st[mid] < 0) r = mid;
				else l = mid;
			}
			search(x - st[(l + r) >> 1] + 1,y);
		}
		if(x < y)
		{
			if(y == 2) {search(x,1); return ;}
			if(y == 1) {ans = 1; return ;}
			int l = 1,r = 60;
			while(l < r and l != r- 1)
			{
				register int mid = l + r >> 1;
				if(y - st[mid] < 0) r = mid;
				else l = mid;
			}
			search(x,y - st[(l + r) >> 1] + 1);
		}
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		f[0] = f[1] = 1;
		for(register int i=1;i<=60;++i) f[i] = f[i-1] + f[i-2];
		st[1] = 3;
		for(register int i=2;i<=60;++i)
			st[i] = st[i-1] + f[i-1];//,cout<<"i = "<<i<<" st[i] = "<<st[i]<<endl;
		int m = get();
		for(register int i=1;i<=m;++i)
		{
			register int l = get(),r = get();
			if(abs(l - r) == 1) {printf("1\n"); continue;}
			search(l,r);
			printf("%lld\n",ans);
		}
		return 0;
	}
}
signed main() {return xin::main();}


T2

权值线段树完全可以搞定

然而我选择了 \(splay\)

其实我应该早一点去学分块的。

我喜欢暴力的数据结构

然后就有了



#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 = 3e5+10;
namespace xin
{
	int a[maxn],n,m;
	class xin_tree{public:int lson,rson,s;}t[maxn<<5];
	#define ls(fa) t[fa].lson
	#define rs(fa) t[fa].rson
	int root[maxn],tot;
	#define up(fa) (t[fa].s = t[ls(fa)].s + t[rs(fa)].s)
	void insert(int &x,int l,int r,int pos,int val)
	{
		if(!x) x = ++tot;
		if(l == r) {t[x].s += val; return ;}
		register int mid = l + r >> 1;
		if(pos > mid) insert(rs(x),mid+1,r,pos,val);
		else insert(ls(x),l,mid,pos,val);
		up(x);
	}
	int query(int fa,int l,int r,int ql,int qr)
	{	
		if(!fa or ql > r or qr < l ) return 0;
		if(ql <= l and qr >= r) return t[fa].s;
		register int mid = l + r >> 1,ret = 0;
		ret += query(ls(fa),l,mid,ql,qr);
		ret += query(rs(fa),mid+1,r,ql,qr);
		return ret;
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get(); m = get();
		for(register int i=1;i<=n;++i) a[i] = get(),insert(root[a[i]],1,n,i,1);
		while(m--)
		{
			register int op = get();
			if(op == 1)
			{
				register int l = get(),r = get(),c = get();
				printf("%d\n",query(root[c],1,n,l,r));
			}
			else
			{
				register int x = get();
				if(a[x] == a[x+1]) continue;
				register int c1 = a[x],c2 = a[x+1];
				insert(root[c1],1,n,x,-1); 	insert(root[c1],1,n,x+1,1);
				insert(root[c2],1,n,x+1,-1);insert(root[c2],1,n,x,1);
				std::swap(a[x],a[x+1]);
			}
		}
		return 0;
	}
}
signed main() {return xin::main();}

还有 lower_bound



#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 = 3e5+10;
namespace xin
{
	class xin_data
	{
		public:
			int color,pos;
			friend bool operator < (xin_data x,xin_data y)
			{return x.color == y.color ? x.pos < y.pos : x.color < y.color;}
	}a[maxn];
	int n,m;
	int pre[maxn];
	int col[maxn],pos[maxn];
	bool vis[maxn];
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile(); outfile();
	#endif
		n = get(); m = get(); bool flag = 0;
		for(register int i=1;i<=n;++i) 
		{	
			a[i].color = get(),a[i].pos = i,pre[i] = a[i].color;
			if(!vis[a[i].color])
				vis[a[i].color] = 1;
			else
				flag = 1;
		}
		if(n <= 1000)
		{
			while(m--)
			{
				register int op = get();
				if(op == 1)
				{
					register int l = get(),r = get(),c = get(),cnt = 0;
					for(register int i=l;i<=r;++i)
						if(pre[i] == c) cnt++;
					printf("%d\n",cnt);
				}
				else
				{
					register int x = get();
					std::swap(pre[x],pre[x+1]);
				}
			}
			return 0;
		}
		std::sort(a+1,a+n+1);
		for(register int i=1;i<=n;++i) col[i] = a[i].color,pos[i] = a[i].pos;
		for(register int i=1;i<=m;++i)
		{
			register int op = get();
//			cout<<"i = "<<i<<' ';
			if(op == 1)
			{	
				register int l = get(),r = get(),val = get();
//				cout<<" l = "<<l<<" r = "<<r<<" color = "<<val<<' ';
				register int p1 = std::lower_bound(col+1,col+n+1,val) - col,p2 = std::upper_bound(col+1,col+n+1,val) - col - 1;
				if(p2 < p1)	{printf("0\n"); continue;}
				register int left = std::lower_bound(pos+p1,pos+p2+1,l) - pos,right = std::lower_bound(pos+p1,pos+p2+1,r) - pos;
				if(pos[right] != r) right --;
//				cout<<"p1 = "<<p1<<" p2 = "<<p2<<" left = "<<left<<" right = "<<right<<endl;
				if(!flag) {printf("%d\n",(bool)(right - left + 1)); continue;}	
				printf("%d\n",right - left + 1);
			}
			else
			{
				register int x = get();
				if(x == n) continue;
				if(pre[x] == pre[x+1]) continue;
				register int c1 = pre[x],c2 = pre[x+1];
				register int p1 = std::lower_bound(col+1,col+n+1,c1) - col,p2 = std::upper_bound(col+1,col+n+1,c1) - col - 1;
				register int y = std::lower_bound(pos+p1,pos+p2+1,x) - pos;
				pos[y] = x + 1;
				p1 = std::lower_bound(col+1,col+n+1,c2) - col; p2 = std::upper_bound(col+1,col+n+1,c2) - col - 1;
				y = std::lower_bound(pos+p1,pos+p2+1,x+1) - pos;
				pos[y] = x;
				std::swap(pre[x],pre[x+1]);
			}
		}
//		for(register int i=1;i<=n;++i)
//			cout<<"i = "<<i<<" ("<<a[i].color<<','<<a[i].pos<<")"<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

T3

还没改完,咕了

posted @ 2021-07-02 21:47  NP2Z  阅读(39)  评论(0编辑  收藏  举报