2019-1005至1007总结

Posted kalginamiemeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019-1005至1007总结相关的知识,希望对你有一定的参考价值。

咕的太多了,赶紧补补。

前面的就写写题解,最近的再写总结。

10/05$Night$

T1

模拟,我采取的方法是记录方向和尾部节点。

但是如果使用$vector$记录路径最后$clear$或是直接用$map$会好一些。

我用了一个二维数组,于是T掉了。

后来考完后把数组开小后AC

没人需要代码吧……

还是放一个:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define N 601
#define isv(i,j) visn[(i)+N][(j)+N]

using namespace std;

int visn[2*N][2*N],ans=0;
vector<pair<int,int> >poss;
struct BLOCK{
	int edx,edy,dir,len;//dir=0(N),1(S),2(W),3(E),-1(U)
	void getpos(){
		poss.clear();
		switch(dir){
			case 0://N↑
				for(int i=0;i<len;i++)
					poss.push_back(make_pair(edx,edy+i));
				break;
			case 1://S↓
				for(int i=0;i<len;i++)
					poss.push_back(make_pair(edx,edy-i));
				break;
			case 2://W←
				for(int i=0;i<len;i++)
					poss.push_back(make_pair(edx-i,edy));
				break;
			case 3://E→
				for(int i=0;i<len;i++)
					poss.push_back(make_pair(edx+i,edy));
				break;
			default:poss.push_back(make_pair(edx,edy));
		}
	}
	void updatevis(){
		switch(dir){
			case 0://N↑
				for(int i=0;i<len;i++)
					isv(edx,edy+i)++;
				break;
			case 1://S↓
				for(int i=0;i<len;i++)
					isv(edx,edy-i)++;
				break;
			case 2://W←
				for(int i=0;i<len;i++)
					isv(edx-i,edy)++;
				break;
			case 3://E→
				for(int i=0;i<len;i++)
					isv(edx+i,edy)++;
				break;
			default:isv(edx,edy)++;
		}

	}
	void clear(){
		this->edx=this->edy=0;
		this->dir=-1;
		this->updatevis();
	}
	void move(const char mq){
		switch(mq){
			case ‘N‘://0↑
				if(this->dir==-1){
					this->edy++;
					this->dir=0;
				}
				else if(this->dir==2 || this->dir==3)//W E
					this->edy++;
				else{
					if(this->dir==0)//N
						this->edy+=this->len;
					else//S
						this->edy++;
					this->dir=-1;//Up
				}
				break;
			case ‘S‘://1↓
				if(this->dir==-1){
					this->edy--;
					this->dir=1;
				}
				else if(this->dir==2 || this->dir==3)//W E
					this->edy--;
				else{
					if(this->dir==0)//N
						this->edy--;
					else//S
						this->edy-=this->len;
					this->dir=-1;//Up
				}
				break;
			case ‘W‘://2←
				if(this->dir==-1){
					this->edx--;
					this->dir=2;
				}
				else if(this->dir==0 || this->dir==1)//N S
					this->edx--;
				else{
					if(this->dir==2)//W
						this->edx-=this->len;
					else//E
						this->edx--;
					this->dir=-1;
				}
				break;
			case ‘E‘://3→
				if(this->dir==-1){
					this->edx++;
					this->dir=3;
				}
				else if(this->dir==0 || this->dir==1)//N S
					this->edx++;
				else{
					if(this->dir==3)//E
						this->edx+=this->len;
					else//W
						this->edx++;
					this->dir=-1;
				}
				break;
			default:puts("Error A Wrong Move");
		}
		this->updatevis();
	}
	void pour(){
		cout<<"("<<this->edx<<","<<this->edy<<")";
		switch(this->dir){
			case -1:
				puts("?");
				break;
			case 0://N
				puts("↑");
				break;
			case 1:
				puts("↓");
				break;
			case 2:
				puts("←");
				break;
			case 3:
				puts("→");
				break;
			default:
				puts("A Error In ‘dir‘");
		}
	}
}bl;
int cn;
char st[N];
int main(){
//	freopen("block.in" ,"r",stdin);
//	freopen("block.out","w",stdout);
	int T;
	cin>>T;
	while(T--){
		memset(visn,0,sizeof visn);
		memset(st,0,sizeof st);
		bl.clear();
		ans=0;
		scanf("%d%s",&bl.len,st+1);
		for(int i=1;st[i]!=0;i++)
			bl.move(st[i]);//bl.pour();
		bl.getpos();
		sort(poss.begin(),poss.end());
		for(int i=0;i<poss.size();i++)
			printf("%d ",poss[i].first);
		puts("");
		for(int i=0;i<poss.size();i++)
			printf("%d ",poss[i].second);
		puts("");
		for(int i=-600;i<=600;i++)
			for(int j=-600;j<=600;j++)
				ans=max(ans,isv(i,j));
		printf("%d
",ans);
	}
}

T2

毒瘤数学题,不会……咕咕咕。

T3

新思路:把一段操作压成一个$hash$值

或者靠这个题的特性,维护值域区间。

于是线段树区间乘,区间加。

代码撂着:

#include <iostream>
#include <cstring>
#include <cstdio>
#define N 222222
#define LL long long

using namespace std;

const int Mod=1995667591,Upbit=333667;
struct XDS{
	int l,r;
	LL add,muilt;
#define lc(k) ((k)<<1)
#define rc(k) (((k)<<1)|1)
}rt[4*N];
int dn,cn,clt;
LL clhs=0;
void build(int k,int l,int r){//cout<<k<<" + "<<l<<" + "<<r<<endl;
	rt[k].l=l,rt[k].r=r;
	rt[k].add=0;
	rt[k].muilt=1;
	if(l==r)
		return ;
	int mid=(l+r)>>1;
	build(lc(k),l    ,mid);
	build(rc(k),mid+1,r);
}
void downlazy(int k){
	if(rt[k].l!=rt[k].r){
		if(rt[k].muilt!=1){
			rt[lc(k)].muilt=(rt[lc(k)].muilt*rt[k].muilt)%Mod;
			rt[rc(k)].muilt=(rt[rc(k)].muilt*rt[k].muilt)%Mod;
			rt[lc(k)].add  =(rt[lc(k)].add  *rt[k].muilt)%Mod;
			rt[rc(k)].add  =(rt[rc(k)].add  *rt[k].muilt)%Mod;
			rt[k].muilt=1;
		}
		if(rt[k].add){
			rt[lc(k)].add=(rt[lc(k)].add+rt[k].add)%Mod;
			rt[rc(k)].add=(rt[rc(k)].add+rt[k].add)%Mod;
			rt[k].add=0;
		}
	}
}
void add(int k,int l,int r,LL v){//cout<<"-----------------------------------------------------
Add:"<<k<<endl 									 <<"RTL:"<<rt[k].l<<endl 									 <<"RTR:"<<rt[k].r<<endl 									 <<"QEL:"<<l<<endl 									 <<"QER:"<<r<<endl 									 <<"QRV:"<<v<<endl;
	if(l<=rt[k].l && rt[k].r<=r){
		rt[k].add=(v+rt[k].add)%Mod;
		return ;
	}
	if(rt[k].l==rt[k].r)return ;
	downlazy(k);
	int mid=(rt[k].l+rt[k].r)>>1;
	if(l<=mid)
		add(lc(k),l,r,v);
	if(r>mid)
		add(rc(k),l,r,v);
}
void muilt(int k,int l,int r,LL v){//cout<<"===================================================
Muilt:"<<k<<endl 									   <<"RTL:"<<rt[k].l<<endl 									   <<"RTR:"<<rt[k].r<<endl 									   <<"QEL:"<<l<<endl 									   <<"QER:"<<r<<endl 									   <<"QRV:"<<v<<endl;
	if(l<=rt[k].l && rt[k].r<=r){
		rt[k].add  =(v*rt[k].add)%Mod;
		rt[k].muilt=(v*rt[k].muilt)%Mod;
		return ;
	}
	if(rt[k].l==rt[k].r)return ;
	downlazy(k);
	int mid=(rt[k].l+rt[k].r)>>1;
	if(l<=mid)
		muilt(lc(k),l,r,v);
	if(r>mid)
		muilt(rc(k),l,r,v);
}
int getans(int k){
	if(rt[k].l==rt[k].r){
		//cout<<k<<"----"<<rt[k].add<<"("<<clhs<<")"<<endl;
		return rt[k].add==clhs;
	}
	downlazy(k);
	return getans(lc(k))+getans(rc(k));
}
int main(){
	int a,b,c;
	scanf("%d%d%d",&dn,&clt,&cn);
	build(1,1,dn);
	for(LL i=1;i<=clt;i++)
		clhs=((clhs*Upbit)+i)%Mod;
	for(int i=1;i<=cn;i++){
		scanf("%d%d%d",&a,&b,&c);
		muilt(1,a,b,Upbit);
		add  (1,a,b,c);
	}
	printf("%d
",getans(1));
}

 10/06

Codeforces & AtCoder

T1-(Codeforces Round #434 Div. 1)D. Wizard‘s Tour

<题目链接>

题目被翻译了,还被改名了 ??

不管了。

这是虎的加强版。

贪心。在图上DFS,形成一棵搜索树。

那么可以把边分为鸡肋几类

不是通向父节点的两两配对,

通向父节点的分类讨论,和下面剩下的配,其次贡献给父节点

这样贪心的结果是可以保证的,最多只有根节点有一条边被浪费。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define M 222222
#define N 222222

using namespace std;

struct SR{
	int next,t;
	bool is_des,is_tr;
	SR(){next=t=is_des=is_tr=0;}
}rs[2*M];
int pn,
	edn,
	cnt=0,
	fl[N],
	deg[N];
bool is_v[N],
	 usdfa[N];
struct ANS{
	int f,m,t;
	ANS(int a,int b,int c):f(a),m(b),t(c){}
};
vector<ANS>ans;
void add(int f,int t){
	rs[cnt].t=t;
	rs[cnt].next=fl[f];
	fl[f]=cnt++;
}
void dfs(int k,int pre,int pp){//cout<<k<<"<-"<<pp<<endl;
	is_v[k]=1;
	int ls=0,lstid;
	if(pre!=-1)rs[pre].is_tr=rs[pre^1].is_tr=1;
	for(int i=fl[k];i!=-1;i=rs[i].next){
		int t=rs[i].t;
		if(rs[i].is_des || t==pp)continue;
		if(!is_v[t]){
			dfs(t,i,k);
			if(!usdfa[t])deg[k]++;
			else continue;
		}
		else if(!rs[i].is_tr)
			deg[k]++;
		if(ls){
			ans.push_back(ANS(ls,k,t));
			rs[lstid  ].is_des=			rs[lstid^1].is_des=			rs[i]      .is_des=			rs[i^1]    .is_des=1;
			ls=0;
		}
		else {
			ls=t;
			lstid=i;
		}
	}
	if(pre==-1)return ;
	if(deg[k]&1){
		usdfa[k]=1;
		if(ls!=0){
			rs[pre  ].is_des=			rs[pre^1].is_des=			rs[lstid].is_des=			rs[lstid^1].is_des=1;
			ans.push_back(ANS(pp,k,ls));
		}
	}
}
int main(){
	int a,b;
	//freopen("1.in","r",stdin);
	memset(fl,-1,sizeof fl);
	scanf("%d%d",&pn,&edn);
	for(int i=1;i<=edn;i++){
		scanf("%d%d",&a,&b);
		add(a,b);
		add(b,a);
	}
	for(int i=1;i<=pn;i++){
		if(!is_v[i]){
			dfs(i,-1,-1);
		}
	}
	printf("%d
",ans.size());
	for(int i=0;i<ans.size();i++)
		printf("%d %d %d
",ans[i].f,ans[i].m,ans[i].t);
}

T2-AtCoder Grand Round #1  F.Wide Swap

<题目链接>

序列神题。

用拓扑维护数之间的不变关系。

加上线段树优化建图。

没有过$QAQ$

T3-Codeforces Round #200 Div.1 E Tree ( ? )

说是上面的题,蒟蒻麦蒙在CF官网上翻了半天愣是没有……

结论题,答案就是所有边权之和(%%%出题人)

简单证明一番。

我们想要最大值,于是可以转化为经过最小值的次数最少。

于是把最小值的边经过一次并删除,分成两棵树。

对这两棵树分别进行上述操作就可以得到次小和次次小值。

重复上述操作。可以得出结论,所有的边只会被经过一次。

于是就结束了,至于代码,放一个也行……

#include <cstdio>

using namespace std;

long long pn,c,ans;
int main(){
	scanf("%lld",&pn);
	for(int i=1;i<pn;i++){
		scanf("%*d%*d%lld",&c);
		ans+=c;
	}
	printf("%lld
",ans);
}

20191007

总结

时间分配还可以,T3分得有点少了。

所以T3的dp跪了。

得与失

得:

  1. 想了一些优化手段。
  2. 打了不同的部分分。
  3. $dp$的意识(雾

失:

  1. 又没写对拍。(没正解或是没暴力)
  2. $dp$的柿子并没有推清楚

结果

25
860郭本一 50
03:11:03
5
03:11:03
11
03:13:31
66
03:13:31

话说$T2$为啥作差不加绝对值啊……

给题解留个坑$Huge lfloor floor$

以上是关于2019-1005至1007总结的主要内容,如果未能解决你的问题,请参考以下文章

python常用代码片段总结

BootStrap有用代码片段(持续总结)

Android开发常用代码片段

BootStrap实用代码片段(持续总结)

回归 | js实用代码片段的封装与总结(持续更新中...)

查看发票组代码后的总结和有感