2.14模拟总结

前言

节日快乐!

(逃)
day10
50pts
期望:10+30+20=60
实际:0+30+20=50
rnk11

彻彻底底的摆烂局了。
但是rnk竟然没有太掉,所以我应该并不孤独…
和KH并排坐在机房里,各自看着电脑,痴痴想着各自的心事,一坐就是三个小时。
半小时三题了属于是
T1挂分是因为把题目描述的"连线"理解成了线段,但实际上是直线。
我不太确定还和KH统一了一下意见
个人感觉这个题意是真的很模糊,为什么不在比赛主页强调而要在钉钉啊!谁比赛的时候还会看钉钉啊qwq
事实是我那个靠着毁天灭地的剪枝竟然能过30,我也是惊了。

题目解析

圆与连线(circle)

挺妙的题目。
其实没有想像中那么难。
但完全没有往这边想过。
(而且题意都混淆不清)

考虑每个点落在圆上的两个切点,其对应两个旋转角组成一个区间。两个点可以同时存在的充要条件是其对应的区间相交且不包含。
然后就变成了线段问题,先按照左端点排序,然后暴力枚举第一条线段,把所有与它合法相交的线段提出来,拿右端点直接做一个最长上升子序列就行了。
(好久没写队列的最长上升子序列了,竟然莫名其妙的有些怀念)

转移石子(rock)

都叫它模拟费用流,但个人感觉这更像反悔贪心吧…
其实我考场上的大方向是对的,但是这个反悔没太整明白。
关键是给每配一对的权值加个-inf,这样就自然而然的保证必然会选满。
然后就是尝试在LCA处合并,并将反悔元素重新插入。
讨论一下几个深度的大小关系就可以得出,配对后两个反悔元素同时选取必然是不优的,所以不必担心同时取式子出bug的问题。(个人认为题解这个地方的讲解十分草率

藏宝地图(treasure)

神仙扫描线dp。
完全没有往这方面想过…由于看到连通块一共只有 O ( k ) O(k) O(k) 个,所以一直以为是数据结构题,疯狂尝试建 k 棵树套树。
这个题最妙的地方应该就是对于障碍的处理了,通过奇技淫巧避免了十分麻烦的上下转移,确实十分巧妙。
一个细节问题是要注意障碍要先加后删。

代码

T1

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
	ll x(0),f(1);char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
void write(ll x){
	if(x>9) write(x/10);
	putchar('0'+x%10);
}
const int N=2e3+100;
const double pai=acos(-1.0);
const double eps=1e-10;

int n,m;
int r;
int x[N],y[N];
struct line{
	double x,y;
	bool operator < (const line oth)const{return abs(x-oth.x)>eps?x<oth.x:y<oth.y;}
}l[N];
int ans;
double a[N],q[N];
int tot,num;
int f=0;
void calc(){
	num=0;
	for(int i=1;i<=tot;i++){
		if(!num||a[i]>q[num]-eps) q[++num]=a[i];
		else{
			int st=1,ed=num;
			while(st<ed){
				int mid=(st+ed)>>1;
				if(q[mid]>a[i]-eps) ed=mid;
				else st=mid+1;
			}
			q[st]=a[i];
		}
		//printf("i=%d num=%d\n",i,num);
	}
	ans=max(ans,num);
	if(f){
		for(int i=1;i<=tot;i++) printf("%lf ",a[i]);
		printf("\nnum=%d\n\n",num);
	}
}

signed main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);

	n=read();r=read();
	
	for(int i=1;i<=n;i++){
		x[i]=read();y[i]=read();
		double g=atan2(y[i],x[i]),d=acos(1.0*r/sqrt(x[i]*x[i]+y[i]*y[i]));
		l[i].x=g-d;l[i].y=g+d;
		if(l[i].x<-pai) l[i].x+=2*pai;
		if(l[i].y>pai) l[i].y-=2*pai;
		if(f) printf("(%lf %lf)\n",l[i].x/pai,l[i].y/pai);
		if(l[i].x>l[i].y) swap(l[i].x,l[i].y);
	}	
	if(f) puts("");
	sort(l+1,l+1+n);
	if(f) for(int i=1;i<=n;i++) printf("(%lf %lf)\n",l[i].x,l[i].y);
	for(int now=1;now<=n;now++){
		a[tot=1]=l[now].y;
		for(int i=now+1;i<=n&&l[i].x<l[now].y+eps;i++){
			if(l[i].y>l[now].y-eps) a[++tot]=l[i].y;
		}
		calc();
	}
	printf("%d\n",ans);
	return 0;
}
/*
*/

T2

#include<bits/stdc++.h>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
	ll x(0),f(1);char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
void write(ll x){
	if(x>9) write(x/10);
	putchar('0'+x%10);
}
const int N=3e5+100;
const int M=2e6+100;
const double pai=acos(-1.0);
const ll inf=1e12;

int n,m;
int dis[M],ls[M],rs[M];
ll val[M],tot,rub[M],num;
inline int New(ll v){
	int now=num?rub[num--]:++tot;
	val[now]=v;
	ls[now]=rs[now]=0;dis[now]=0;
	//printf(" New: now=%d v=%lld\n",now,v);
	return now;
}
int merge(int x,int y){
	if(!x||!y) return x|y;
	if(val[x]>val[y]) swap(x,y);
	rs[x]=merge(rs[x],y);
	if(dis[rs[x]]>dis[ls[x]]) swap(ls[x],rs[x]);
	dis[x]=dis[rs[x]]+1;
	return x;
}
inline ll top(int &x,int op=0){
	if(!x) return 1e18;
	ll res=val[x];
	if(op) rub[++num]=x,x=merge(ls[x],rs[x]);
	return res;
}
struct node{
	int to,nxt,w;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y,int w){
	p[++cnt]=(node){y,fi[x],w};fi[x]=cnt;
}
ll dep[N];
__gnu_pbds::priority_queue<ll,greater<ll>>a[N],b[N];
int xx[N],yy[N];
ll ans,S;
void dfs(int x,int f){
	for(int i=fi[x];~i;i=p[i].nxt){
		int to=p[i].to;
		if(to==f) continue;
		dep[to]=dep[x]+p[i].w;
		dfs(to,x);
		a[x].join(a[to]);
		b[x].join(b[to]);
	}
	//printf("\ndfs: x = %d\n",x);
	int o=min(xx[x],yy[x]);xx[x]-=o;yy[x]-=o;
	S-=o;
	if(xx[x]){
		for(int i=1;i<=xx[x];i++){
			//printf("  ins A: %lld\n",dep[x]);
			a[x].push(dep[x]);
		}
	}
	else if(yy[x]){
		//printf("  ins B: %lld\n",dep[x]-inf);
		for(int i=1;i<=yy[x];i++){
			b[x].push(dep[x]-inf);
		}
	}
	//printf("  a=%d topa=%lld b=%d topb=%lld\n",a[x],top(a[x]),b[x],top(b[x]));
	while(!a[x].empty()&&!b[x].empty()){
		ll u=a[x].top(),v=b[x].top();
		if(u+v-2*dep[x]>=0) break;
		ans+=u+v-2*dep[x];
		a[x].pop();b[x].pop();
		a[x].push(-v+2*dep[x]);
		b[x].push(-u+2*dep[x]);
	}
	return;
}

signed main(){
	//freopen("rock.in","r",stdin);
	//freopen("rock.out","w",stdout);
	memset(fi,-1,sizeof(fi));cnt=-1;
	dis[0]=-1;
	n=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read(),w=read();
		//printf("(%d %d %d)\n",x,y,w);
		addline(x,y,w);addline(y,x,w);
	}
	for(int i=1;i<=n;i++) xx[i]=read(),yy[i]=read(),S+=yy[i];
	dfs(1,0);
	printf("%lld\n",ans+S*inf);
	return 0;
}
/*
*/

T3

#include<bits/stdc++.h>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
	ll x(0),f(1);char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
void write(ll x){
	if(x>9) write(x/10);
	putchar('0'+x%10);
}
const int N=1e6;
const ll inf=1e12;

int n,m;
int o=1e6;

#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)
int tr[N<<2],laz[N<<2];
inline void pushup(int k){
	tr[k]=tr[ls]+tr[rs];
}
inline void tag(int k){
	tr[k]=0;laz[k]=0;
	return;
}
inline void pushdown(int k){
	if(laz[k]!=-1){
		laz[k]=-1;
		tag(ls);tag(rs);
	}
	return;
}
int ask(int k,int l,int r,int x,int y){
	if(x>y) return 0;
	if(x<=l&&r<=y) return tr[k];
	pushdown(k);
	int res(0);
	if(x<=mid) res+=ask(ls,l,mid,x,y);
	if(y>mid) res+=ask(rs,mid+1,r,x,y);
	return res;
}
void add(int k,int l,int r,int p,int w){
	if(l==r){
		tr[k]+=w;return;
	}
	pushdown(k);
	if(p<=mid) add(ls,l,mid,p,w);
	else add(rs,mid+1,r,p,w);
	pushup(k);
	return;
}
void clear(int k,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		tag(k);return;
	}
	pushdown(k);
	if(x<=mid) clear(ls,l,mid,x,y);
	if(y>mid) clear(rs,mid+1,r,x,y);
	pushup(k);
}

//0:block
//1:treasure
//2:query
struct ope{
	int op,f;
	int x,y,id;
	int l,r;
	bool operator < (const ope oth)const{
		if(y!=oth.y) return y>oth.y;
		else if(op!=oth.op) return op<oth.op;
		else return f>oth.f;
	}
}q[N<<1];
int tot;
int val[N],ans[N];

multiset<int>s;
multiset<int>::iterator it;

signed main(){
	//freopen("treasure.in","r",stdin);
	//freopen("treasure.out","w",stdout);	
	o+=2;
	memset(laz,-1,sizeof(laz));
	
	m=read();
	for(int i=1;i<=m;i++){
		int a=read(),b=read(),c=read(),d=read();
		++a;++b;++c;++d;
		q[++tot]=(ope){0,1,0,d,i,a,c};
		q[++tot]=(ope){0,-1,0,b-1,i,a,c};
	}
	m=read();
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
		++x;++y;
		q[++tot]=(ope){1,0,x,y,0,0,0};
	}
	n=read();
	for(int i=1;i<=n;i++){
		int x=read(),y=read();
		++x;++y;
		q[++tot]=(ope){2,0,x,y,i,0,0};
	}
	sort(q+1,q+1+tot);
	
	s.insert(o);
	for(int i=1;i<=tot;i++){
		if(q[i].op==0){
			int l=q[i].l,r=q[i].r,id=q[i].id,ed=(*s.lower_bound(q[i].l));
			if(q[i].f==1){
				s.insert(l-1);s.insert(r);
				int res=ask(1,1,o,l,ed);
				val[id]=ask(1,1,o,r+1,ed);
				clear(1,1,o,l,r);
				add(1,1,o,l-1,res);
			}
			else{
				s.erase(s.find(l-1));s.erase(s.find(r));
				add(1,1,o,l-1,-val[id]);
				clear(1,1,o,l,r);
			}
		}
		else if(q[i].op==1) add(1,1,o,q[i].x,1);
		else{
			int pos=q[i].x;
			int ed=(*s.lower_bound(pos));
			ans[q[i].id]=ask(1,1,o,pos,ed);
		}
	}
	for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
	return 0;
}
/*

1 3

*/

总结

昨天:“现在大部分题目基本上考场上都能想到正确的方向了”
今天就直接两道题完全抓瞎…
《天 高 地 厚》
就这考试也有人AK是我没想到的。
收下我的膝盖!

明天加油吧!awa

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: smcdraw2.14是一种数字化的绘图软件,它具有各种绘图功能和工具,可以帮助用户轻松进行图形设计和绘制。smcdraw2.14具有简洁易用的界面,适合初学者和专业设计师使用。 首先,smcdraw2.14具有丰富的绘图功能,用户可以使用各种形状和线条工具创建各种图形,如矩形、圆形、箭头等。同时,它还提供了丰富的颜色、线型和填充选项,使用户能够根据自己的需求进行个性化的设计。 其次,smcdraw2.14还具有强大的编辑功能。用户可以调整图形的大小、位置和旋转角度,还可以改变图形的颜色和透明度。此外,smcdraw2.14还提供了各种绘制和编辑工具,如剪切、复制、粘贴、重排等,方便用户对绘图进行修改和操作。 此外,smcdraw2.14还支持导入和导出多种文件格式,用户可以将绘制的图形保存为常见的图像格式,如PNG、JPG等,以便后续使用。同时,用户还可以将已有的图像导入到smcdraw2.14中进行编辑和修改。 最后,smcdraw2.14还具有实用的辅助工具,如标尺和网格线,可以帮助用户更精确地进行绘图。此外,该软件还支持撤销和重做功能,用户可以轻松地回到先前的操作步骤。 总之,smcdraw2.14是一款功能强大、操作简便的数字化绘图软件,它适用于各类用户,无论是初学者还是专业设计师,都可以通过smcdraw2.14实现高质量的绘图和设计。 ### 回答2: smcdraw2.14是一个特定的名词或短语,无法明确其含义和提供具体回答。请提供更多相关信息或背景,以便我可以为您提供更有针对性的答案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值