[Comet OJ - Contest #7]简要题解?

似乎由于是NOI前所以没什么dalao打
混了个rk4_(:з」∠)_

签到题

相邻两个数gcd=1

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;

int ty;
ll l,r;

int main() {
	for(scanf("%d",&ty);ty;ty--) {
		scanf("%lld%lld",&l,&r);
		printf("%lld %d %d %d\n",(l==r)?r:r*(r-1),l,r,(l==r)?r:1);
	}
}

麻将题

大力bfs

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

const int N=1e5+5;

int dis[N],a[N],q[N];

int Id() {
	int ret=0;
	fo(i,1,4) ret=ret*5+a[i];
	return ret;
}

void out(int *a,int x) {fd(i,4,1) a[i]=x%5,x/=5;}

int main() {
	int hd=0,tl=0,x;
	memset(dis,255,sizeof(dis));
	a[1]=1;a[2]=2;a[3]=3;a[4]=4;x=Id();q[++tl]=x;dis[x]=0;
	a[1]=4;a[2]=1;a[3]=2;a[4]=3;x=Id();q[++tl]=x;dis[x]=0;
	a[1]=3;a[2]=4;a[3]=1;a[4]=2;x=Id();q[++tl]=x;dis[x]=0;
	a[1]=2;a[2]=3;a[3]=4;a[4]=1;x=Id();q[++tl]=x;dis[x]=0;
	while (hd<tl) {
		int x=q[++hd];
		out(a,x);
		fo(i,1,4) {
			swap(a[i],a[i==4?1:i+1]);
			int y=Id();
			if (dis[y]==-1) dis[y]=dis[x]+1,q[++tl]=y;
			swap(a[i],a[i==4?1:i+1]);
		}
	}
	scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]);
	printf("%d\n",dis[Id()]);
	return 0;
}

临时翻出来的题

把贡献拆开大力状压

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;

const int S=(1<<16)+5,N=17;

int cnt[S],n,p[N],ty;
ll f[S],g[S];

int main() {
	fo(s,0,(1<<16)-1) fo(i,0,15) cnt[s]+=s>>i&1;
	for(scanf("%d",&ty);ty;ty--) {
		scanf("%d",&n);
		ll ans=0;
		fo(i,1,n) scanf("%d",&p[i]);
		// y*a[x]
		fo(s,0,(1<<n)-1) f[s]=g[s]=0;g[0]=1;
		fo(s,0,(1<<n)-2) {
			int x=cnt[s]+1;
			fo(i,1,n) 
				if (i!=p[x]&&!(s>>(i-1)&1)) {
					int sum=0;
					fo(j,i+1,n) if (s>>(j-1)&1) sum+=j;
					f[s|(1<<i-1)]+=f[s]+g[s]*sum*x;
					g[s|(1<<i-1)]+=g[s];
				}
		}
		ans+=f[(1<<n)-1];
		// x*a[y]
		fo(s,0,(1<<n)-1) f[s]=g[s]=0;g[0]=1;
		fo(s,0,(1<<n)-2) {
			int x=cnt[s]+1;
			fo(i,1,n) 
				if (i!=p[x]&&!(s>>(i-1)&1)) {
					int sum=0;
					fo(j,1,i-1) if (!(s>>(j-1)&1)) sum+=j;
					f[s|(1<<i-1)]+=f[s]+g[s]*sum*x;
					g[s|(1<<i-1)]+=g[s];
				}
		}
		ans+=f[(1<<n)-1];
		// x*a[x]
		fo(s,0,(1<<n)-1) f[s]=g[s]=0;g[0]=1;
		fo(s,0,(1<<n)-2) {
			int x=cnt[s]+1;
			fo(i,1,n) 
				if (i!=p[x]&&!(s>>(i-1)&1)) {
					int sum=0;
					fo(j,i+1,n) if (s>>(j-1)&1) sum++;
					f[s|(1<<i-1)]+=f[s]+g[s]*sum*x*i;
					g[s|(1<<i-1)]+=g[s];
				}
		}
		ans-=f[(1<<n)-1];
		// y*a[y]
		fo(s,0,(1<<n)-1) f[s]=g[s]=0;g[0]=1;
		fo(s,0,(1<<n)-2) {
			int x=cnt[s]+1;
			fo(i,1,n) 
				if (i!=p[x]&&!(s>>(i-1)&1)) {
					int sum=0;
					fo(j,1,i-1) if (!(s>>(j-1)&1)) sum++;
					f[s|(1<<i-1)]+=f[s]+g[s]*sum*x*i;
					g[s|(1<<i-1)]+=g[s];
				}
		}
		ans-=f[(1<<n)-1];
		printf("%lld\n",ans);
	}
	return 0;
}

机器学习题

显然可以求凸包
但是我懒直接大力决策单调性

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;
typedef double db;

int read() {
	char ch;int sig=1;
	for(ch=getchar();ch<'0'||ch>'9';ch=getchar()) if (ch=='-') sig=-1;
	int x=ch-'0';
	for(ch=getchar();ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
	return x*sig;
}

const int N=2e5+5;
const ll inf=1e16;

struct node{int x,y;}a[N];

bool cmp(node a,node b) {return a.x<b.x;}

int n,sta[N],top;
ll pre[N],suf[N],ans;

ll calc(int l,int r) {return suf[r]+pre[l]+(ll)(a[r].x-a[l].x)*(a[r].x-a[l].x);}

void solve(int l,int r,int L,int R) {
	if (l==r) {
		fo(i,L,R) ans=min(ans,calc(i,l));
		return;
	}
	int id=0,mid=l+r>>1;ll mn=inf;
	fo(i,L,R) {
		ll tmp=calc(i,mid);
		if (tmp<mn) mn=tmp,id=i;
	}
	ans=min(ans,calc(id,mid));
	solve(l,mid,L,id);solve(mid+1,r,id,R);
}

int main() {
	freopen("d.in","r",stdin);
	freopen("d.out","w",stdout);
	n=read();
	fo(i,1,n) a[i].x=read(),a[i].y=read();
	sort(a+1,a+n+1,cmp);
	ll sum=0;
	for(int l=1,r=0;l<=n;l=r+1) {
		while (r<n&&a[r+1].x==a[l].x) r++;
		fo(i,l,r) pre[i]=sum;
		fo(i,l,r) sum+=a[i].y<0?-a[i].y:0;
	}
	sum=0;
	for(int r=n,l=n+1;r>=1;r=l-1) {
		while (l>1&&a[l-1].x==a[r].x) l--;
		fo(i,l,r) suf[i]=sum;
		fo(i,l,r) sum+=a[i].y>0?a[i].y:0;
	}
	ans=inf;
	solve(1,n,1,n);
	printf("%lld\n",ans);
	return 0;
}

毒瘤题

显然条件相当于圆在所给点集的凸包内
考虑一组询问,相当于将凸包往里面缩r的距离,然后判断点(x,y)是否在凸包内
可以离线,将询问按r排序,维护往里面缩的凸包上每条边的消失时间,在一条边消失时更新其两边的两条边
不想写

最简单的题

lxl大毒瘤
看完题就跑了
讲一下我yy的根号做法,没有实现(写nm呢
考虑按操作分块,对于一个块内的所有询问按x排序,所有没有被修改的点按x排序,维护个指针扫过去用链表维护所有连续段,把一个连续段的贡献打在左端点
对于一个询问,首先二分出左右端点所在的连续段,剩余的相当于求某个区间和,这个也可以分块维护,二分的东西可以用线段树维护
然后,把所有修改按位置排序,依次枚举,维护当前连续段的右端点即可更新修改的影响
大概是 O ( ( n + m ) m ) O((n+m)\sqrt m) O((n+m)m )的吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值