【NOIP模拟】斐波那契+序列+栅栏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38083668/article/details/82973182

T1:

     Hash

代码(map实现):

#include <bits/stdc++.h>
#include <tr1/unordered_map>
using namespace std;
using namespace std::tr1;

const int Max=100010;
int n,m,tot,ans=1;
int fib[50],p[Max];
unordered_map<long long,bool>vis;

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}

int main()
{
	fib[1]=1;
	for(int i=2;i<=42;i++) fib[i]=fib[i-1]+fib[i-2];
	n=get_int(),p[++tot]=get_int(),vis[p[1]]=1;
	for(int i=2;i<=n;i++)
	{
	  int x=get_int(),tag=0;
	  for(int j=42;j>=1;j--)
	  {
	  	if(fib[j]-x<=0) break;
	    if(vis[fib[j]-x]){tag=1;break;}
	  }
	  if(tag) p[tot=1]=x,ans++,vis.clear(),vis[x]=1;
	  else p[++tot]=x,vis[x]=1;
	}
	cout<<ans;
	return 0;
}

T2:

     主席树。

代码(30分平衡树):

#include <bits/stdc++.h>
#define int long long 
using namespace std;

const int Max=100005;
int n,m,tot,root,s,pos;
int num[Max],f[1005][1005];
struct shu{int l,r,data,num,size,cnt;};
shu a[1005];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}
inline void print(int x)
{
	if(x<0) x=-x,putchar('-');
	if(x>9) print(x/10);
	putchar('0'+x%10);
}

inline void update(int p){a[p].size=a[a[p].l].size+a[a[p].r].size+a[p].cnt;}
inline int NEW(int x)
{
	a[++tot].num=x,a[tot].data=rand();
	a[tot].size=a[tot].cnt=1;
	return tot;
}
inline void zig(int &p)
{
	int q=a[p].l;
	a[p].l=a[q].r,a[q].r=p,p=q;
	update(a[p].r),update(p);
}
inline void zag(int &p)
{
	int q=a[p].r;
	a[p].r=a[q].l,a[q].l=p,p=q;
	update(a[p].l),update(p);
}
inline void Insert(int &p,int x)
{
	if(!p){p=NEW(x);return;}
	if(a[p].num==x) {a[p].cnt++,update(p);return;}
	if(x<a[p].num)
	{
	  Insert(a[p].l,x);
	  if(a[a[p].l].data>a[p].data) zig(p);
	}
	else
	{
	  Insert(a[p].r,x);
	  if(a[a[p].r].data>a[p].data) zag(p);
	}
	update(p);
}
inline int find(int p,int x)
{
	if(a[a[p].l].size>=x) return find(a[p].l,x);
	if(a[a[p].l].size+a[p].cnt>=x) return a[p].num;
	return find(a[p].r,x-a[a[p].l].size-a[p].cnt);
}

inline void pre()
{
	for(int i=1;i<=n;i++)
	{
	  memset(a,0,sizeof(a)),root=s=tot=0;
	  for(int j=i;j>=1;j--)
	  {
	  	Insert(root,num[j]),s++;
	  	pos=(s%2)?s/2+1:s/2;
	  	f[i][i-j+1]=find(root,pos);
	  }
	}
}

signed main()
{
	n=get_int();
	for(int i=1;i<=n;i++) num[i]=get_int();
	pre();
	m=get_int();
	for(int i=1;i<=m;i++)
	{
	  int l1=get_int(),r1=get_int(),l2=get_int(),r2=get_int(),ans=0;
	  for(int i=l2;i<=n;i++)
	    for(int j=l2;j<=r2;j++) if(f[i][j]>=l1&&f[i][j]<=r1) ans++;
	  print(ans),putchar('\n');
	}
	return 0;
}

代码(100分主席树):

#include <bits/stdc++.h>
using namespace std;

const int Max=100005;
int n,m,tot;
int root[Max*20],num[Max],lc[Max*20],rc[Max*20];
long long tree[Max*20],ans;

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}
inline void print(long long x)
{
	if(x<0) x=-x,putchar('-');
	if(x>9) print(x/10);
	putchar('0'+x%10);
}

inline void add(int fa,int &now,int l,int r,int x)
{
	now=++tot,tree[now]=tree[fa]+1,lc[now]=lc[fa],rc[now]=rc[fa];
	if(l==r) return;
	int mid=(l+r)>>1;
	if(x<=mid) add(lc[fa],lc[now],l,mid,x);
	else add(rc[fa],rc[now],mid+1,r,x);
}
inline long long Q(int root1,int root2,int l,int r,int x)
{
	if(x>=r) return tree[root1]-tree[root2];
	int mid=(l+r)>>1;
	if(x<=mid) return Q(lc[root1],lc[root2],l,mid,x);
	return Q(lc[root1],lc[root2],l,mid,x)+Q(rc[root1],rc[root2],mid+1,r,x);
}

inline long long solve(int x,int l,int r)
{
	int d=0;
	ans=0,tot=0,memset(tree,0,sizeof(tree)),memset(root,0,sizeof(root));
	memset(lc,0,sizeof(lc)),memset(rc,0,sizeof(rc));
	add(root[1],root[1],0,2*n,n);
	for(int i=1;i<=n;i++)
	{
	  d+=((num[i]<=x)?1:-1);
	  add(root[i],root[i+1],0,2*n,n+d);
	  ans+=Q(root[max(i-l+1,0)],root[max(i-r,0)],0,2*n,d+n);
	}
	return ans;
}

int main()
{
	n=get_int();
	for(int i=1;i<=n;i++) num[i]=get_int();
	m=get_int();
	while(m--)
	{
	  int x1=get_int(),y1=get_int(),x2=get_int(),y2=get_int();
	  print(solve(y1,x2,y2)-solve(x1-1,x2,y2)),putchar('\n');
	}
	return 0;
}

T3:

     随机化+二维树状数组

代码(请忽略define部分。。。):
 

#define dzyo_ak_uoi long long
#include <bits/stdc++.h>
using namespace std;

const int Max=2010;
int n,m,q;
dzyo_ak_uoi sum[Max][Max];
map<pair<pair<int,int>,pair<int,int> >,int>S;

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}
inline void print(int x)
{
	if(x<0) x=-x,putchar('-');
	if(x>9) print(x/10);
	putchar('0'+x%10);
}

inline void add(int x,int y,dzyo_ak_uoi num)
{
	for(int i=x;i<=n;i+=i&(-i))
	  for(int j=y;j<=m;j+=j&(-j))
	    sum[i][j]^=num;
}
inline dzyo_ak_uoi Q(int x,int y)
{
	dzyo_ak_uoi ans=0;
	for(int i=x;i;i-=i&(-i))
	  for(int j=y;j;j-=j&(-j))
	    ans^=sum[i][j];
	return ans;
}

int main()
{
	srand(time(0));
	n=get_int(),m=get_int(),q=get_int();
	while(q--)
	{
	  int tag=get_int(),x1=get_int(),y1=get_int(),x2=get_int(),y2=get_int();
	  if(tag==1)
	  {
		dzyo_ak_uoi num=rand()*65536+rand();
	    add(x1,y1,num),add(x2+1,y1,num),add(x1,y2+1,num),add(x2+1,y2+1,num);
	    S[make_pair(make_pair(x1,y1),make_pair(x2,y2))]=num;
	  }
	  if(tag==2)
	  {
		dzyo_ak_uoi ad=S[make_pair(make_pair(x1,y1),make_pair(x2,y2))];
	    add(x1,y1,ad),add(x2+1,y1,ad),add(x1,y2+1,ad),add(x2+1,y2+1,ad);
	  }
	  if(tag==3) (Q(x1,y1)==Q(x2,y2))?cout<<"Yes\n":cout<<"No\n";
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38083668/article/details/82973182