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題爲線段樹題,看的心累,就留待以後解決吧