3.22

hdu1348 (凸包模板題)最小長度代表凸包

題意是說一個國王給你一些點,這些點組成一個城堡,國王要求在這個多邊形形狀的城堡周圍建起周長最小的城牆,並且城牆與城堡的距離處處不得小於L。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1006;
const double pi=acos(-1.0);
struct node{
	double x,y;
}p[maxn],P[maxn];
int n,tot;
double ans;
double X(node a,node b,node c){
	return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double len(node a,node b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(node a,node b){
	double pp=X(p[0],a,b);
	if(pp>0) return true;
	if(pp<0) return false;
	return len(p[0],a)<len(p[0],b);
}
int main(){
	int t;double l;
	cin>>t;
	for(int cas=1;cas<=t;cas++){
		if(cas!=1) printf("\n");
		scanf("%d%lf",&n,&l);
		ans=2*pi*l;
	//	cout<<ans<<endl;
		for(int i=0;i<n;i++){
			scanf("%lf%lf",&p[i].x,&p[i].y);
		}
		if(n==1)
		printf("%.0f\n",ans);
		else if(n==2){
			printf("%.0f\n",ans+len(p[0],p[1]));
		}
		else{
			for(int i=0;i<n;i++){
				if(p[i].y<p[0].y)
				swap(p[i],p[0]);
				else if(p[i].y==p[0].y&&p[i].x<p[0].x)
				swap(p[i],p[0]);
			}
			sort(p+1,p+n,cmp);
		
			P[0]=p[0];
			P[1]=p[1];
			tot=1;
			for(int i=2;i<n;i++){
				while(tot>0&&X(P[tot-1],P[tot],p[i])<=0) tot--;
				tot++;
				P[tot]=p[i];
			}
			for(int i=0;i<tot;i++){
				ans+=len(P[i],P[i+1]);
			}
			ans+=len(P[0],P[tot]);
			printf("%.0f\n",ans);
		}
		
	}
	
	return 0;
}

cf 546D

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn];int r;
int b[maxn];
vector<int> q[maxn];
vector<int> ::iterator it;
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	cin>>a[i];
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		q[y].push_back(x);
	}
	for(int i=n-1;i>=0;i--){
		if((b[a[i]])==n-1-i-r&&i!=n-1) r++;
		else for(it=q[a[i]].begin();it!=q[a[i]].end();it++)  b[*it]++;
	}
	cout<<r<<endl;
	return 0;
}

首先我的思維是這種的,就是首先限定範圍,那個誰和所有的相連的數量,但是苦於遞歸比較詭異。

而且吊兒郎當的,最後沒時間寫了,要會用數據結構,貪心。換過去就不會再換回來,至少換一個之類的。要轉化爲這種,比如,從小到大,不要跳躍。

hdu1754

#include<bits/stdc++.h>
using namespace std;
const int maxnode=1<<19;
const int maxn=2e6+10;
struct node{
	int value;
	int left,right;
}node[maxnode];
int father[maxn];
void buildtree(int i,int left,int right){
	node[i].left=left;
	node[i].right=right;
	node[i].value=0;
	if(left==right){
		father[left]=i;
		return ;
	}
	buildtree(i<<1,left,(int)(floor(left+right)/2.0));
	buildtree((i<<1)+1,(int)(floor(left+right)/2.0)+1,right);
	
	
} 
void updatetree(int ri){
	if(ri==1) return;
	int fi=ri/2;
	int a =node[fi<<1].value;
	int b=node[(fi<<1)+1].value;
	node[fi].value=max(a,b);
	updatetree(ri/2); 
}
int Max;
void query(int i,int l,int r){
	if(node[i].left==l&&node[i].right==r){
		Max=max(Max,node[i].value);
		return;
	}
	i=i<<1;
	if(l<=node[i].right){
		if(r<=node[i].right) query(i,l,r);
		else query(i,l,node[i].right);
	}
	i++;
	if(r>=node[i].left)
	if(l>=node[i].left) query(i,l,r);
	else query(i,node[i].left,r);
}
int main(){
	int n,m,q;
	ios::sync_with_stdio(false);
	while(cin>>n>>m){
		buildtree(1,1,n);
		for(int i=1;i<=n;i++){
			cin>>q;
			node[father[i]].value=q;
			updatetree(father[i]);
		}
		string op;
		int a,b;
		while(m--){
			cin>>op>>a>>b;
			if(op[0]=='Q'){
				Max=0;
				query(1,a,b);
				cout<<Max<<endl;
				
			}
			else {
				node[father[a]].value=b;
				updatetree(father[a]);
			}
		}
	}
}

線段樹模板題

POJ3468

區間求和和區間修改

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N=1e5+10;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll sum[N<<2],add[N<<2];
struct node{
	int l,r;
	int mid(){
		return (l+r)>>1;
	}
}tree[N<<2];
void push_up(int rt){
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
	
}
void push_down(int rt,int m){
	if(add[rt]) {
		add[rt<<1]+=add[rt];
		add[rt<<1|1]+=add[rt];
		sum[rt<<1]+=add[rt]*(m-(m>>1));
		sum[rt<<1|1]+=add[rt]*(m>>1);
		add[rt]=0;
	}
}
void build(int l,int r,int rt){
	tree[rt].l=l;
	tree[rt].r=r;
	add[rt]=0;
	if(l==r){
		scanf("%I64d",&sum[rt]);
		return;
	}
	int m=tree[rt].mid();
	build(lson);
	build(rson);
	push_up(rt);
}
void update(int c,int l,int r,int rt){
	if(tree[rt].l==l&&tree[rt].r==r){
		add[rt]+=c;
		sum[rt]+=(ll)c*(r-l+1);
		return ;
	}
	if(tree[rt].l==tree[rt].r){
		return;
	}
	push_down(rt,tree[rt].r-tree[rt].l+1);
	int m=tree[rt].mid();
	if(r<=m){
		update(c,l,r,rt<<1);
	}
	else if(l>m) update(c,l,r,rt<<1|1);
	else {
		update(c,l,m,rt<<1);
		update(c,m+1,r,rt<<1|1);
	}
	push_up(rt);
	
}
ll query(int l,int r,int rt){
	if(l==tree[rt].l&&r==tree[rt].r) return sum[rt];
	push_down(rt,tree[rt].r-tree[rt].l+1);
	int m=tree[rt].mid();
	ll res=0;
	if(r<=m) res+=query(l,r,rt<<1);
	else if(l>m) res+=query(l,r,rt<<1|1);
	else {
		res+=query(l,m,rt<<1);
		res+=query(m+1,r,rt<<1|1);
	}
	return res;
}
int main(){
	int n;
	int m;
	while(~scanf("%d%d",&n,&m)){
		build(1,n,1);
		while(m--){
			char ch[2];
			scanf("%s",&ch);
			int a,b,c;
			if(ch[0]=='Q'){
				scanf("%d%d",&a,&b);
				printf("%lld\n",query(a,b,1));
			}
			else {
				scanf("%d%d%d",&a,&b,&c);
				update(c,a,b,1);
			}
		}
	}
	return 0;
	
}

cf546 E題爲線段樹題,看的心累,就留待以後解決吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章