zoukankan      html  css  js  c++  java
  • 7.6总结

    7.6总结

    得分情况

    估分:60+100+60=220

    实际:80+50+0=130

    打挂了110分??!(ノ=Д=)ノ┻━┻

    还我Rank3!!!

    T1

    题目大意

    所以小G作为铁杆歌迷,也计划带着小Y去看周杰伦的演唱会。 演唱会当然要圈出一个空地,然后才能布置道具。 演唱会的第一站,公司临时跟当地的消防局借了n个栏杆,打算用这n个栏杆围出一个矩形。而麻烦的是,这些栏杆有长有短,这就给围场地带来了一些难度。 所以公司聘请你来写一个程序,计算用这n个栏杆做多围出面积多大的矩形。
    (注:必须要刚好围成一个矩形,即不能出现多余的边长,且不能切断栏杆,但所给栏杆不一定要全部用上)

    一开始打了一个错误的暴力:枚举边长再(4*2^n)把边组合起来

    后来打了(5^n)的暴力才发现是错的

    但是在随机数据下第一种方法有不错的正确率

    于是把两种做法结合起来就有了80pts的好成绩

    正解

    考虑状压

    设f[s]表示选了s这个集合,这个集合里的栏杆能分成长度相等的两组(每个都必须选)

    (2^n)枚举,再背包一下就好了

    然后(3^n)枚举两个交集为空的集合,取最大值就好了

    T2

    题目大意

    为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石桥。这个景点造好之后一直没敢对外开放,原因是池塘里有不少危险的食人鱼。
      豆豆先生酷爱冒险,他一听说这个消息,立马赶到了池塘,想做第一个在桥上旅游的人。虽说豆豆爱冒险,但也不敢拿自己的性命开玩笑,于是他开始了仔细的实地勘察,并得到了一些惊人的结论:食人鱼的行进路线有周期性,这个周期只可能是2,3或者4个单位时间。每个单位时间里,食人鱼可以从一个石墩游到另一个石墩。每到一个石墩,如果上面有人它就会实施攻击,否则继续它的周期运动。如果没有到石墩,它是不会攻击人的。
      借助先进的仪器,豆豆很快就摸清了所有食人鱼的运动规律,他要开始设计自己的行动路线了。每个单位时间里,他只可以沿着石桥从一个石墩走到另一个石墩,而不可以停在某座石墩上不动,因为站着不动还会有其它危险。如果豆豆和某条食人鱼在同一时刻到达了某座石墩,就会遭到食人鱼的袭击,他当然不希望发生这样的事情。
      现在豆豆已经选好了两座石墩Start和End,他想从Start出发,经过K个单位时间后恰好站在石墩End上。假设石墩可以重复经过(包括Start和End),他想请你帮忙算算,这样的路线共有多少种(当然不能遭到食人鱼的攻击)。

     1 ≤ N ≤ 50
     1 ≤ K ≤ 2,000,000,000
     1 ≤ NFish ≤ 20

    一眼题,显然矩乘

    因为转移矩阵是变化的,就先处理出每12个单位时间的转移矩阵,再快速幂就好了

    我数组开小了!!!

    T3

    题目大意

    一条项链包含N 个珠子,每个珠子的颜色是1, 2, …, c 中的一种。项链被固定在一个平板上,平板的某个位置被标记位置1,按顺时针方向其他位置被记为2,3,…,N。

    你将要编写的软件系统应支持如下命令:
    1.R k(0 < K < N) 意为Rotate k。将项链在平板上顺时针旋转k 个位置, 即原来处于位置1 的珠子将转至位置k+1,处于位置2 的珠子将转至位置k+2,依次类推。

    2.F 意为Flip。将平板沿着给定的对称轴翻转,原来处于位置1 的珠子不动,位置2 上的珠子与位置N 上的珠子互换,位置3 上的珠子与位置N-1 上的珠子互换,依次类推。

    3.S i j(1≤I,j≤N) 意为Swap i , j。将位置i 上的珠子与位置j 上的珠子互换。

    4.P I j x(1≤I,j≤N,x≤c) 意为Paint i , j , x。将位置i 沿顺时针方向到位置j 的一段染为颜色x。

    5.C 意为Count。查询当前的项链由多少个“部分”组成,我们称项链中颜色相同的一段为一个“部分”。

    6.CS i j(1≤I,j≤N) 意为CountSegment i , j。查询从位置i沿顺时针方向到位置j 的一段中有多少个部分组成。

      1. 对于60%的数据,N ≤ 1 000,Q ≤ 1 000; 
      2. 对于100%的数据,N ≤ 500 000,Q ≤ 500 000,c ≤ 1 000。

    一眼望过去:不就是splay嘛,前几天刚学

    然而没时间打了

    暴力打挂了。。。

    gg

    正解好像是线段树?

    我不管我就要打splay!!

    3537ms,跑最慢…

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    struct qy
    {
    	int ch[2],fa,size,left,right,sum,sam,rev,col;
    };
    
    int n,i,j,c,q,x,y,l1,r1,l2,r2,l,r,s,tot,ans,root,k,kk,gg;
    int a[500005],list[500005];
    char str[10];
    qy tree[500005];
    
    int get(int x)
    {
    	if (tree[tree[x].fa].ch[0]==x) return 0;
    	else return 1;
    }
    
    void change_rev(int x)
    {
    	swap(tree[x].ch[0],tree[x].ch[1]);
    	swap(tree[x].left,tree[x].right);
    	tree[x].rev^=1;
    }
    
    void change_sam(int x,int col)
    {
    	tree[x].sum=1;
    	tree[x].left=col;
    	tree[x].right=col;
    	tree[x].col=col;
    	tree[x].sam=col;
    }
    
    void update(int x)
    {
    	tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1;
    	if (tree[tree[x].ch[0]].left) tree[x].left=tree[tree[x].ch[0]].left;
    	else tree[x].left=tree[x].col;
    	if (tree[tree[x].ch[1]].right) tree[x].right=tree[tree[x].ch[1]].right;
    	else tree[x].right=tree[x].col;
    	if (tree[x].col) tree[x].sum=1;
    	else tree[x].sum=0;
    	if (tree[x].ch[0]) tree[x].sum+=tree[tree[x].ch[0]].sum;
    	if (tree[x].ch[1]) tree[x].sum+=tree[tree[x].ch[1]].sum;
    //	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+1;
    	if ((tree[x].ch[0])&&(tree[tree[x].ch[0]].right==tree[x].col)) tree[x].sum--;
    	if ((tree[x].ch[1])&&(tree[tree[x].ch[1]].left==tree[x].col)) tree[x].sum--;
    }
    
    void pushdown(int x)
    {
    	if (tree[x].rev)
    	{
    		if (tree[x].ch[0]) change_rev(tree[x].ch[0]);
    		if (tree[x].ch[1]) change_rev(tree[x].ch[1]);
    		tree[x].rev=0;
    	}
    	if (tree[x].sam)
    	{
    		if (tree[x].ch[0]) change_sam(tree[x].ch[0],tree[x].sam);
    		if (tree[x].ch[1]) change_sam(tree[x].ch[1],tree[x].sam);
    		tree[x].sam=0;
    	}
    }
    
    void rotate(int x)
    {
    	int y=tree[x].fa;
    	int z=tree[y].fa;
    	int k=get(x);
    	int kk=get(y);
    	if (z) 
    	tree[z].ch[kk]=x;
    	tree[x].fa=z;
    	tree[y].ch[k]=tree[x].ch[k^1];
    	if (tree[x].ch[k^1])
    	tree[tree[x].ch[k^1]].fa=y;
    	tree[x].ch[k^1]=y;
    	tree[y].fa=x;
    	update(y);
    	update(x);
    }
    
    void remove(int x,int y)
    {
    	list[0]=0;
    	while (x!=y)
    	{
    		list[++list[0]]=x;
    		x=tree[x].fa;
    	}
    	for (int i=list[0];i>=1;i--)
    		pushdown(list[i]);
    }
    
    void splay(int x,int goal)
    {
    	remove(x,goal);
    	while (tree[x].fa!=goal)
    	{
    		int y=tree[x].fa;
    		if (tree[y].fa!=goal)
    		{
    			if (get(x)==get(y)) rotate(y);
    			else rotate(x);
    		}
    		rotate(x);
    	}
    	if (goal==0) root=x;
    }
    
    int build(int l,int r,int fa)
    {
    	if (l>r) return 0;
    	int mid=(l+r)/2;
    	int x=++tot;
    	tree[x].fa=fa;
    	tree[x].col=a[mid];
    	tree[x].sam=tree[x].rev=0;
    	tree[x].ch[0]=build(l,mid-1,x);
    	tree[x].ch[1]=build(mid+1,r,x);
    	update(x);
    	return x;
    }
    
    void find(int s)
    {
    	int x=root;
    	while (s!=0)
    	{
    		pushdown(x);
    		if (tree[tree[x].ch[0]].size+1<s)
    		{
    			s-=tree[tree[x].ch[0]].size+1;
    			x=tree[x].ch[1];
    		}
    		else
    		{
    			if (tree[tree[x].ch[0]].size+1==s)
    				s-=tree[tree[x].ch[0]].size+1;
    			else
    				x=tree[x].ch[0];
    		}
    	}
    	splay(x,0);
    }
    
    void Rotate(int x)
    {
    	int k,kk,g;
    	find(n-x+1);
    	k=root;
    	find(n+2);
    	kk=root;
    	splay(k,kk);
    	g=tree[k].ch[1];
    	tree[k].ch[1]=0;
    	update(k);update(kk);
    //	splay(k,0);
    	
    	find(1);
    	k=root;
    	find(2);
    	kk=root;
    	splay(k,kk);
    	tree[k].ch[1]=g;
    //	update(k);update(kk);
    	splay(k,0);
    }
    
    void Flip()
    {
    	int k,kk;
    	find(2);
    	k=root;
    	find(n+2);
    	kk=root;
    	splay(k,kk);
    	change_rev(tree[k].ch[1]);
    }
    
    void Swap(int x,int y)
    {
    	int k,kk;
    	find(x+1);
    	k=root;
    	find(y+1);
    	kk=root;
    	swap(tree[k].col,tree[kk].col);
    	splay(k,0);
    	splay(kk,0);
    }
    
    void Paint(int x,int y,int col)
    {
    	int k,kk;
    	find(x);
    	k=root;
    	find(y+2);
    	kk=root;
    	splay(k,kk);
    	change_sam(tree[k].ch[1],col);
    	update(k);
    	update(kk);
    }
    
    int Count()
    {
    	int k,kk,ans;
    	find(1);
    	k=root;
    	find(n+2);
    	kk=root;
    	splay(k,kk);
    	ans=tree[tree[k].ch[1]].sum;
    	find(2);
    	k=root;
    	find(n+1);
    	kk=root;
    	if ((tree[k].col==tree[kk].col)&&(ans>1)) ans--;
    	return ans;
    }
    
    int CountSegment(int l,int r)
    {
    	find(l);
    	k=root;
    	find(r+2);
    	kk=root;
    	splay(k,kk);
    	return tree[tree[k].ch[1]].sum;
    }
    
    int main()
    {
    	freopen("read.in","r",stdin);
    	freopen("write.out","w",stdout);
    	scanf("%d%d",&n,&c);
    	for (i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	root=build(0,n+1,0);
    	scanf("%d",&q);
    	while (q--)
    	{
    		memset(str,0,sizeof(str));
    		scanf("%s",str+1);
    		if (str[1]=='R')
    		{
    			scanf("%d",&x);
    			Rotate(x);
    		}
    		if (str[1]=='F')
    		{
    			Flip();
    		}
    		if (str[1]=='S')
    		{
    			scanf("%d%d",&x,&y);
    			Swap(x,y);
    		}
    		if (str[1]=='P')
    		{
    			scanf("%d%d%d",&l,&r,&x);
    			if (l<=r)
    			Paint(l,r,x);
    			else
    			{
    				Paint(l,n,x);
    				Paint(1,r,x);
    			}
    		}
    		if ((str[1]=='C')&&(str[2]==0))
    		{
    			printf("%d
    ",Count());
    		}
    		if ((str[1]=='C')&&(str[2]=='S'))
    		{
    			scanf("%d%d",&l,&r);
    			if (l<=r)
    			{
    				ans=CountSegment(l,r);
    			}
    			else
    			{
    				ans=CountSegment(l,n)+CountSegment(1,r);
    				find(n+1);
    				k=root;
    				find(2);
    				kk=root;
    				if (tree[k].col==tree[kk].col) ans--;
    			}
    			printf("%d
    ",ans);
    		}
    	}
    }
    

    小结

    1. 交题之前一定要检查空间,不要开太大也不要开小了
    2. 专心打题,不要东打一点西打一点,容易出错
  • 相关阅读:
    批处理向FTP上传指定属性的文件 批处理增量备份的例子
    基于PHPExcel常用方法总结(phpexcel类库实例)
    Expo大作战(三十四)--expo sdk api之LinearGradient(线性渐变),KeepAwake(保持屏幕不休眠),IntentLauncherAndroid,Gyroscope,
    Expo大作战(三十三)--expo sdk api之MapView(地图),MailComposer(磁力传感计),Lottie(动画)
    Expo大作战(三十二)--expo sdk api之Noifications
    Expo大作战(三十一)--expo sdk api之Payments(expo中的支付),翻译这篇文章傻逼了,完全不符合国内用户,我只负责翻译大家可以略过!
    Expo大作战(三十)--expo sdk api之Permissions(权限管理模块),Pedometer(计步器api)
    生成分类编号的方法
    牛腩学Kotlin做Android应用
    我用Xamarin开发android应用,应用在真机上一打开就退出了
  • 原文地址:https://www.cnblogs.com/leason-lyx/p/11147281.html
Copyright © 2011-2022 走看看