0%

vector

对元素去重

1
2
3
4
5
6
7
vector<int>ve={0, 0, 1, 1, 2, 3};
ve.erase(unique(ve.begin(), ve.end()), ve.end());
for(auto item : ve){
cout << item << " ";
}
output:
0 1 2 3
Read more »

有 $k$ 只麻球,每只活一天就会死亡,临死前可能会生出一些新的麻球。具体来说,生 $i$ 只麻球的概率为 $p_i$ 。给定 $m$ ,求 $m$ 天后所有麻球均死亡的概率。

Read more »

计算几何基础

单位向量 $(Unit\ vector)$

​ 对于任意向量 $\vec a$ ,不论方向如何,若其大小为单位长度,则称其为 $\vec a$ 方向上的单位向量 $(Unit\ vector)$ 。单位向量通常被记为 $\vec u$ 。
特殊地,三维笛卡尔坐标系上的三个基向量 $\vec i=(1,0,0),\vec j=(0,1,0),\vec k=(0,0,1)$ 都是单位向量。
点或向量的结构体如下:

Read more »

POJ 2318 TOYS

分析:就是让你找每个盒子里面有几个玩具,由于坐标都是整数,处理更加简单,二分+叉积判断位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=5000+10;
int sgn(int x){
if(x==0) return 0;
if(x<0) return -1;
else return 1;
}
struct Point{
int x,y;
Point(){}
Point(int x,int y):x(x),y(y){}
Point operator-(const Point& b)const{
return Point(x-b.x,y-b.y);
}
//叉积
int operator ^(const Point &b)const{
return x*b.y-y*b.x;
}
};
int n,m;
struct Line{
Point up,down;
Line(){}
Line(Point up,Point down):up(up),down(down){}
}box[MAXN];
int num[MAXN];
void BinSearch(Point p){
int L=0,R=n+1,ans;
while(L<=R){
int mid=L+((R-L)>>1);
if(sgn((box[mid].up-p)^(box[mid].down-p))<0){
ans=mid;
R=mid-1;
}else{
L=mid+1;
}
}
num[ans-1]++;
}
int main(){
while(~scanf("%d",&n)&&n){
int x1,y1,x2,y2,x,y;
scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
box[0]=Line(Point(x1,y1),Point(x1,y2));
box[n+1]=Line(Point(x2,y1),Point(x2,y2));
for(int i=1;i<=n;i++){
scanf("%d%d",&box[i].up.x,&box[i].down.x);
box[i].up.y=y1; box[i].down.y=y2;
}
Point p;
memset(num,0,sizeof num);
while(m--){
scanf("%d%d",&p.x,&p.y);
BinSearch(p);
}
for(int i=0;i<=n;i++){
printf("%d: %d\n",i,num[i]);
}
puts("");
}
}
Read more »

很久没写线段树了,今天写了一个线段树的模版题,单点修改和区间查询最小值。
不知道为什么,就输入一个字符,%c超时,换成%s就过了。

hdu-1754-status

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=2e5+10;
int score[MAXN],tree[MAXN<<2];
int N,M;
void Build_tree(int o,int L,int R){
if(L==R){
tree[o]=score[L];
return ;
}
int mid=L+((R-L)>>1);
Build_tree(o<<1,L,mid);
Build_tree(o<<1|1,mid+1,R);
tree[o]=max(tree[o<<1],tree[o<<1|1]);
}
void Update(int o,int L,int R,int idx,int val){
if(L==R){
tree[o]=val;
return ;
}
int mid=L+((R-L)>>1);
if(idx<=mid) Update(o<<1,L,mid,idx,val);
else Update(o<<1|1,mid+1,R,idx,val);
tree[o]=max(tree[o<<1],tree[o<<1|1]);
}
int Query(int o,int L,int R,int ql,int qr){
if(ql<=L&&qr>=R) return tree[o];
int mid=L+((R-L)>>1);
int ret=0;
if(ql<=mid) ret=max(ret,Query(o<<1,L,mid,ql,qr));
if(qr>mid) ret=max(ret,Query(o<<1|1,mid+1,R,ql,qr));
return ret;
}
int main(){
while(~scanf("%d%d",&N,&M)){
for(int i=1;i<=N;i++){
scanf("%d",&score[i]);
}
Build_tree(1,1,N);
char order;
int l,r;
while(M--){
scanf("%s%d%d",&order,&l,&r);//如果用%c会超时,神奇
if(order=='Q'){
printf("%d\n",Query(1,1,N,l,r));
}else if(order=='U'){
Update(1,1,N,l,r);
}
}
}
return 0;
}

Area

For a given polygon g, computes the area of the polygon.

g is represented by a sequence of points $p_1$, $p_2$,…, $p_n$ where line segments connecting pi and pi+1 (1 ≤ in−1) are sides of g. The line segment connecting pn and p1 is also a side of the polygon.

Read more »