Contents
1 AdHoc 1
1.1 Calculation . . . 1
1.2 CountDigit . . . 2
2 shik 2 2.1 IntervalQuery_2 . . . 2
2.2 QTREE . . . 2
2.3 poj3675 . . . 3
2.4 SimplexTriathlon . . . 4
2.5 FFT_IntMul . . . 4
2.6 GeneralMatching . . . 5
2.7 ManhattanMST . . . 5
2.8 PartitionTree . . . 5
2.9 Hopcroft . . . 6
2.10 MiinmumEnclosingCircle . . . 6
2.11 PolyMul . . . 6
2.12 InervalQuery . . . 6
2.13 ConvexPolygonDistence . . . 7
2.14 KM_BFS . . . 7
2.15 KMP . . . 8
2.16 DLX . . . 8
2.17 EMST . . . 8
2.18 ReadDouble . . . 10
2.19 LinearInverse . . . 10
2.20 HarmonicNumber . . . 10
2.21 CircleUnionArea . . . 10
2.22 MillerRabin . . . 11
2.23 RightTriangleConstruction . . . 11
2.24 LineIntersection . . . 11
2.25 KD_Tree . . . 11
2.26 FarthestPointPair . . . 12
2.27 Splay_Seq . . . 12
2.28 3DConvexBody . . . 13
2.29 HalfPlaneIntersection . . . 13
2.30 Poker . . . 14
2.31 KM_DFS . . . 14
2.32 SimplexDitch . . . 15
2.33 Dinic . . . 15
2.34 IntegerPartition . . . 16
3 Strings 16 3.1 KMPDM . . . 16
3.2 Aho-Corasick . . . 16
3.3 ArticalCompare . . . 16
3.4 KMP . . . 17
3.5 Palindrome . . . 17
3.6 Suffix Array . . . 17
4 Graph 18 4.1 SCCDM . . . 18
4.2 DMST . . . 18
4.3 MatchFlowDM . . . 18
4.4 HungarianDM . . . 19
4.5 PlanarRegion . . . 19
4.6 FKT . . . 20
5 First 20 5.1 default . . . 20
5.2 vimrc . . . 20
6 Number Theory 20 6.1 Prime Testing . . . 20
6.2 NTT . . . 21
7 Geometry 21 7.1 3DlineIntersect . . . 21
7.2 ConvexHull . . . 22
7.3 ConvexHullDM . . . 22
7.4 Point . . . 22
7.5 HalfPlane . . . 22
7.6 Polygon . . . 23
7.7 MaxInsideCircle . . . 23
7.8 3DRotate . . . 24
8 DiscreteMath 24 8.1 IntegerSequence . . . 24
8.2 SquareRoot . . . 24
8.3 Gauss . . . 24
8.4 Difference . . . 25
8.5 StorWagner . . . 25
8.6 GCD . . . 25
9 Miscellaneous 25 9.1 Date . . . 25
9.2 DebugList . . . 25
1 AdHoc
1.1 Calculation
#include<iostream>
#include<map>
#include<string>
using namespace std;
map<string,string>H;
map<string,int>used;
int t;
long long calc(string &s,bool &flag,int &offset);
bool is_digit(char c){return c>=’0’&&c<=’9’;}
bool is_number(char c){return (c>=’0’&&c<=’9’)||c==’-’;}
bool is_alpha(char c){return (c>=’A’&c<=’Z’)||(c>=’a’&&c<=’z
’);}
long long calc(int n,long long d[],char op[]){
int i,j;
for(i=j=0;i<=n;i++){
while(i<n&&op[i]==’*’){
d[j]*=d[i+1];
i++;
}
if(i+1<=n){
d[j+1]=d[i+1];
op[j]=op[i];
j++;
} }
for(i=0;i<j;i++){
if(op[i]==’+’)d[0]+=d[i+1];
else d[0]-=d[i+1];
}
return d[0];
}
long long getNum(string &s,bool &flag,int &offset){
if(s[offset]==’(’){
offset++;
return calc(s,flag,offset);
}
if(is_number(s[offset])){
long long an=0;
bool neg;
if(s[offset]==’-’){
neg=1;
offset++;
}
else neg=0;
while(offset<s.size()&&is_digit(s[offset])){
an*=10;
an+=s[offset]-’0’;
offset++;
}
if(neg)return -an;
return an;
} else{
int tmp=offset;
while(tmp<s.size()&&(is_alpha(s[tmp])||(is_digit(s[
tmp]))))tmp++;
string str=s.substr(offset,tmp-offset);
offset=tmp;
if(used[str]==t){
flag=false;
return-1;
}
used[str]=t;
int offset2=0;
long long an=calc(H[str],flag,offset2);
used[str]=0;
return an;
}
return -1;
}
long long calc(string &s,bool &flag,int &offset){
//cout<<"test:"<<s<<endl;
long long d[100];
char op[100];
int n=0;
if(s[offset]==’-’)d[n]=0;
else d[n]=getNum(s,flag,offset);
//cout<<"d[n]:"<<d[n]<<endl;
if(!flag)return -1;
while(offset<s.size()&&s[offset]!=’)’){
op[n++]=s[offset++];
d[n]=getNum(s,flag,offset);
//cout<<"d[n]:"<<d[n]<<endl;
if(!flag){
return-1;
} }
if(s[offset]==’)’)offset++;
return calc(n,d,op);
}
void myprint(string str){
long long an;
int offset=0;
bool flag=true;
if(H.count(str)==0){
cout<<"UNDEF"<<endl;
return;
}
used[str]=t;
an=calc(H[str],flag,offset);
if(flag==false)cout<<"UNDEF"<<endl;
else cout<<an<<endl;
} main(){
int i,tmp;
string str;
while(getline(cin,str)){
tmp=str.find_first_not_of(" ");
if(tmp<0)continue;
str=str.substr(tmp);
str=str.substr(0,str.find_last_not_of(" ")+1);
if(str.compare(0,6,"PRINT ")==0){
t++;
myprint(str.substr(6));
}
else if(str.compare("RESET")==0){
H.clear();
used.clear();
} else{
for(i=str.size()-1;i>=0;i--) if(str[i]==’ ’)str.erase(i,1);
tmp=str.find(":=");
string str1=str.substr(0,tmp);
string str2=str.substr(tmp+2);
H[str1]=str2;
used[str1]=0;
} } }
1.2 CountDigit
#include<stdio.h>
int an[10];
int mypow(int x,int y){
int an=1;
while(y){ if(y&1) an*=x; x*=x; y>>=1; } return an;
}
void f(int n,int flag){
if(n<=0)return;
int i,j,now=0,ten;
for(i=1,ten=10;ten<=n;i++,ten*=10){
for(j=0;j<=9;j++){
if(j>0)an[j]+=flag*mypow(10,i-1);
if(i>1)an[j]+=flag*(i-1)*mypow(10,i-2)*9;
} }
ten/=10,i--;
int first=1;
while(ten>=1){
int ll=n/ten%10;
if(first) j=1; else j=0;
for(;j<ll;j++) an[j]+=flag*mypow(10,i);
if(i){
for(j=0;j<10;j++)
an[j]+=flag*mypow(10,i-1)*(ll-first)*i;
}
an[ll]+=flag*(n%ten+1);
ten/=10;
i--;
first=0;
} }
int main(){
int A,B,i;
while(scanf("%d%d",&A,&B)&&A){
for(i=0;i<10;i++)an[i]=0;
f(B,1),f(A-1,-1);
for(i=0;i<10;i++){
if(i)putchar(’ ’);
printf("%d",an[i]);
} puts("");
}
return 0;
}
2 shik
2.1 IntervalQuery_2
// by shik
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 200010
#define S 1000010 using namespace std;
typedef long long LL;
LL ans[N];
struct Q { int id,L,R;
void read( int _id ) { id=_id; scanf("%d%d",&L,&R); } } q[N];
int n,m,num[N],tmt;
bool cp( Q a, Q b ) { int ax=a.L/tmt,bx=b.L/tmt;
if ( ax!=bx ) return ax<bx;
return (ax&1)?a.R<b.R:a.R>b.R;
}
void input() {
scanf("%d%d",&n,&m);
for ( int i=1; i<=n; i++ ) scanf("%d",num+i);
for ( int i=0; i<m; i++ ) q[i].read(i);
tmt=(int)(1.514*sqrt(m)+1);
sort(q,q+m,cp);
}
int st,ed,app[S]; LL now;
LL go( int L, int R ) {
while ( st<L ) { now-=num[st]*(1+2*--app[num[st]]); st++;
}
while ( ed>R ) { now-=num[ed]*(1+2*--app[num[ed]]); ed--;
}
while ( st>L ) { st--; now+=num[st]*(1+2*app[num[st]]++);
}
while ( ed<R ) { ed++; now+=num[ed]*(1+2*app[num[ed]]++);
} return now;
}
void solve() {
st=ed=1; app[num[1]]++; now=num[1];
for ( int i=0; i<m; i++ ) ans[q[i].id]=go(q[i].L,q[i].R);
for ( int i=0; i<m; i++ ) printf("%I64d\n",ans[i]);
}
int main() {
input();
solve();
return 0;
}
2.2 QTREE
// by shik
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define FOR(it,c) for ( __typeof((c).begin()) it=(c).begin()
; it!=(c).end(); it++ )
#define N 10010
#define PB push_back using namespace std;
typedef vector<int> VI;
struct LCT {
int nv,fa[N],fb[N],ch[N][2],val[N],big[N];
void init( int n, int *_val ) { nv=n;
for ( int i=1; i<=n; i++ ) { fa[i]=ch[i][0]=ch[i][1]=0;
val[i]=big[i]=_val[i];
fb[i]=2;
} }
void pull( int x ) {
big[x]=max(val[x],max(big[ch[x][0]],big[ch[x][1]]));
}
void join( int x, int y, int d ) { if ( d<2 ) ch[y][d]=x;
fa[x]=y; fb[x]=d;
}
void rotate( int x ) { int y=fa[x],d=fb[x];
join(ch[x][!d],y,d);
join(x,fa[y],fb[y]);
join(y,x,!d);
pull(y); //pull(x);
}
void splay( int x, int f=0 ) {
while ( fb[x]!=2 && fa[x]!=f ) rotate(x);
pull(x);
return;
while ( fb[x]!=2 && fa[x]!=f ) { int y=fa[x];
if ( fb[x]==fb[y] ) rotate(y);
else rotate(x);
if ( fb[x]!=2 && fa[x]!=f ) rotate(x);
} }
void access( int y, int flg=0, int x=0 ) { while ( y ) {
splay(y);
if ( flg && fa[y]==0 ) printf("%d\n",max(big[ch[y ][1]],big[x]));
fb[ch[y][1]]=2;
join(x,y,1); pull(y);
x=y; y=fa[y];
} }
void link( int x, int y ) { access(x);
join(x,y,2);
access(x);
}
void cut( int x ) { access(x);
splay(x);
join(ch[x][0],0,2);
ch[x][0]=0;
}
void change( int x, int v ) { access(x);
splay(x);
val[x]=v;
pull(x);
}
void query( int x, int y ) { access(x,0);
access(y,1);
}
void debug() {
puts("========= debug =========");
for ( int i=0; i<=nv; i++ ) printf("%d: fa=%d, fb=%d, lch=%d, rch=%d, val=%d, big=%d\n",i,fa[i],fb[i],ch[
i][0],ch[i][1],val[i],big[i]);
} } lct;
int n,ea[N],eb[N],ec[N],val[N],dep[N];
VI e[N];
void input() { scanf("%d",&n);
for ( int i=1; i<=n; i++ ) e[i]=VI();
for ( int i=1; i<n; i++ ) { scanf("%d%d%d",ea+i,eb+i,ec+i);
e[ea[i]].PB(eb[i]);
e[eb[i]].PB(ea[i]);
} }
void dfs( int p, int f, int lv ) { dep[p]=lv;
FOR(it,e[p]) if ( *it!=f ) dfs(*it,p,lv+1);
}
void build() { dfs(1,0,1);
for ( int i=1; i<n; i++ )
if ( dep[ea[i]]<dep[eb[i]] ) swap(ea[i],eb[i]);
for ( int i=1; i<n; i++ ) val[ea[i]]=ec[i];
lct.init(n,val);
for ( int i=1; i<n; i++ ) lct.link(ea[i],eb[i]);
}
void solve() { char op[8];
int a,b;
while ( ~scanf("%s",op) && op[0]!=’D’ ) { scanf("%d%d",&a,&b);
if ( op[0]==’C’ ) { lct.change(ea[a],b);
} else if ( op[0]==’Q’ ) { lct.query(a,b);
} else puts("QQ");
} }
int main() {
int t;
scanf("%d",&t);
while ( t-- ) { input();
build();
solve();
}
return 0;
}
2.3 poj3675
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define maxn 60
#define M_PI 3.14159265358979323846
#define sqr(v) ((v)*(v))
double my_acos(double d) { return acos(d>1?1:d<-1?-1:d
); }
double my_sqrt(double d) { return sqrt(max(d, 0.0));
}
const double eps = 1E-8;
int sig(double d) {
return (d>eps) - (d<-eps);
}
struct Point { double x, y;
Point(){}
Point(double x, double y) : x(x), y(y) {}
Point resize(double d) { d /= my_sqrt(x*x+y*y);
return Point(x*d, y*d);
}
Point left90() { return Point(-y, x);
}
Point operator - (const Point & o) const { return Point(this->x-o.x, this->y-o.y);
}
Point operator + (const Point & o) const { return Point(this->x+o.x, this->y+o.y);
}
Point operator * (double d) const { return Point(x*d, y*d);
}
void output() {
printf("x = %.2f, y = %.2f\n", x, y);
} };
double cross(Point o, Point a, Point b) {
return (a.x-o.x)*(b.y-o.y) - (b.x-o.x)*(a.y-o.y);
}
double dot(Point o, Point a, Point b) {
return (a.x-o.x)*(b.x-o.x) + (a.y-o.y)*(b.y-o.y);
}
double dis(Point a, Point b) {
return my_sqrt(sqr(a.x-b.x) + sqr(a.y-b.y));
}
int btw(Point o, Point a, Point b) { return sig(dot(o,a,b));
}
struct Circle { Point center;
double radis;
};
//return distance from point o to line ab, //res is the projection point of o on ab.
double pointToLine(Point o, Point a, Point b, Point & res) { double d = dis(a, b);
double s = cross(a, b, o) / d;
res = o + (a-b).left90()*(s/d);
return fabs(s);
}
//point vs circle: 1=intersect 0=tangent -1=no intersect int intersect(Point a, Point b, Circle c, Point &p1, Point &
p2) { Point p;
double d = pointToLine(c.center, a, b, p);
int v = sig(c.radis-d);
if(v != -1) {
Point vec = (b-a).resize( my_sqrt(sqr(c.radis)-sqr(d)) )
; p1 = p+vec;
p2 = p-vec;
}
return v;
}
//circle c and triangle oab signed area
double intersectArea(Circle c, Point a, Point b) { if(sig(cross(c.center,a,b))==0) return 0.0; //co-linear Point o = c.center, p[5];
double r = c.radis;
int len = 0;
p[len++] = a;
if(1 == intersect(a,b,c,p[1],p[2])) { //orthogonal if(btw(p[1],a,b)<0) p[len++]=p[1];
if(btw(p[2],a,b)<0) p[len++]=p[2];
}
p[len++]=b;
if(len==4 && btw(p[1],p[0],p[2])>0) swap(p[1], p[2]);
//init over!
double res = 0;
for(int i = 0; i < len-1; i ++) {
if( sig(dis(o,p[i])-r)>0 || sig(dis(o,p[i+1])-r)>0 ) { //outer! sector
double theta = my_acos( dot(o,p[i],p[i+1])/dis(o,p[i]) /dis(o,p[i+1]) );
res += theta * r * r / 2.0;
} else { //inner, triangle
res += fabs(cross(o, p[i], p[i+1])/2.0);
} }
if(sig(cross(o,a,b))<0) res = -res; //signed area return res;
}
//return c and simple polygon ps intersect area double intersectArea(Circle c, Point * ps, int n) {
ps[n] = ps[0];
double res = 0;
for(int i = 0; i < n; i ++) {
res += intersectArea(c,ps[i],ps[i+1]);
}
return fabs(res);
}
//poj-3675 Point ps[maxn];
int n;
int main() { Circle c;
c.center = Point(0,0);
while(scanf("%lf%d", &c.radis, &n) != EOF) { for(int i = 0; i < n; i ++) {
scanf("%lf%lf", &ps[i].x, &ps[i].y);
}
printf("%.2f\n", intersectArea(c, ps, n));
}
return 0;
}
2.4 SimplexTriathlon
#include <iostream>
#include <cstdio>
#include <cmath>
#define FOR(x,y,z) for(int x(y);x<=z;++x) using namespace std;
const double eps=1e-13,inf=1e100;
const int M=101,N=5;
double a[M][N],b[M][4];
int n,m,k;
void pivot(int l,int e) {
double t=-a[l][e]; a[l][e]=-1;
FOR(j,0,n) a[l][j]/=t;
FOR(i,0,m) if (i!=l && abs(a[i][e])>eps) { t=a[i][e]; a[i][e]=0;
FOR(j,0,n) a[i][j]+=a[l][j]*t;
} }
void solve() { for(;;) {
int e,l; l=0; double t,tmax=-inf;
for (e=n;e>0;--e) if (a[0][e]>eps) break;
if (e==0) return;
FOR(i,1,m) if (a[i][e]<-eps && (t=a[i][0]/a[i][e])>
tmax) tmax=t+eps, l=i;
if (l==0) return;
pivot(l,e);
} }
bool check(int t) {
FOR(i,0,m) FOR(j,0,n) a[i][j]=0;
int p=0;
FOR(i,1,k) if (i!=t) { ++p;
FOR(j,1,3) a[p][j]+=b[i][j]-b[t][j], a[p][0]+=b[i][j ]-b[t][j];
a[p][0]*=eps; a[p][0]-=1e-8;
}
double tmin=inf; int l;
FOR(i,1,m) if (a[i][0]<tmin) tmin=a[i][0], l=i;
if (tmin>eps) return true;
FOR(i,1,m) a[i][n]=1; a[0][n]=-1; pivot(l,n); solve();
return abs(a[0][0])<eps;
}
int main() {
cin>>k; n=4; m=k-1;
FOR(i,1,k) FOR(j,1,3) cin>>b[i][j], b[i][j]=1e6/b[i][j];
FOR(i,1,k) cout<<(check(i)?"Yes":"No")<<endl;
}
2.5 FFT_IntMul
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 20010 using namespace std;
const double PI=acos(-1.0);
struct vir{
double re,im;
vir( double _re=0, double _im=0 ):re(_re),im(_im){}
};
vir operator +( vir a, vir b ) { return vir(a.re+b.re,a.im+b .im); }
vir operator -( vir a, vir b ) { return vir(a.re-b.re,a.im-b .im); }
vir operator *( vir a, vir b ) { return vir(a.re*b.re-a.im*b .im,a.re*b.im+a.im*b.re); }
vir x1[2*N],x2[2*N];
int rev( int x, int len ) { int r=0,i;
for ( i=0; i<len; i++,x>>=1 ) r=(r<<1)+(x&1);
return r;
}
void change( vir *x, int len, int loglen ) { for ( int i=0; i<len; i++ )
if ( rev(i,loglen)<i ) swap(x[rev(i,loglen)],x[i]);
}
void fft( vir *x, int len, int loglen ) { change(x,len,loglen);
int i,j,s,t=1;
for ( i=0; i<loglen; i++,t<<=1 ) { for ( s=0; s<len; s+=t+t ) {
vir a,b,wo(cos(PI/t),sin(PI/t)),wn(1,0);
for ( j=s; j<s+t; j++ ) { a=x[j]; b=x[j+t]*wn;
x[j]=a+b; x[j+t]=a-b;
wn=wn*wo;
} } } }
void dit_fft( vir *x, int len, int loglen ) { int i,j,s,t=len>>1;
for ( i=0; i<loglen; i++,t>>=1 ) { for ( s=0; s<len; s+=t+t ) {
vir a,b,wn(1,0),wo(cos(PI/t),-sin(PI/t));
for ( j=s; j<s+t; j++ ) {
a=x[j]+x[j+t]; b=(x[j]-x[j+t])*wn;
x[j]=a; x[j+t]=b;
wn=wn*wo;
} } }
change(x,len,loglen);
for ( i=0; i<len; i++ ) x[i].re/=len;
}
char a[N],b[N];
int main() {
int i,len1,len2,len,loglen,t,over,cas;
scanf("%d",&cas);
while ( cas-- ) { scanf("%s%s",a,b);
len1=strlen(a); len2=strlen(b);
for ( len=1,loglen=0; len<2*len1||len<2*len2; len<<=1 ) loglen++;
for ( i=0; i<len; i++ ) { x1[i]=vir(i<len1?a[i]-’0’:0);
x2[i]=vir(i<len2?b[i]-’0’:0);
}
fft(x1,len,loglen); fft(x2,len,loglen);
for ( i=0; i<len; i++ ) x1[i]=x1[i]*x2[i];
dit_fft(x1,len,loglen);
for ( i=len1+len2-2,over=len=0; i>=0; i-- ) { t=(int)(x1[i].re+over+0.5);
a[len++]=t%10;
over=t/10;
}
for ( ; over; over/=10 ) a[len++]=over%10;
for( len--; len>0&&a[len]==0; len-- );
for ( i=len; i>=0; i-- ) putchar(a[i]+’0’);
putchar(’\n’);
}
return 0;
}
2.6 GeneralMatching
// General Matching O(n^3~4??)
#include <cstdio>
#include <cstring>
#define N 250
int n,g[N][N],match[N],inque[N],que[N],head,tail,father[N], base[N],inblossom[N];
int pop() { return que[head++]; }
void push( int i ) { inque[que[++tail]=i]=1; } int LCA( int u, int v ) {
int inpath[N]={};
for ( u=base[u]; u; u=base[father[match[u]]] ) inpath[u ]=1;
for ( v=base[v]; !inpath[v]; v=base[father[match[v]]] );
return v;
}
void reset( int u, int anc ) { for ( int v; u!=anc; u=v ) {
v=match[u];
inblossom[base[v]]=inblossom[base[u]]=1;
v=father[v];
if ( base[v]!=anc ) father[v]=match[u];
} }
void contract( int u, int v ) { int anc=LCA(u,v);
for ( int i=1; i<=n; i++ ) inblossom[i] = 0;
reset(u,anc); reset(v,anc);
if ( base[u]!=anc ) father[u] = v;
if ( base[v]!=anc ) father[v] = u;
for ( int i=1; i<=n; i++ ) if ( inblossom[base[i]] ) {
base[i]=anc;
if ( !inque[i] ) push(i);
} }
void augment( int u ) { for ( int v,w; u; u=w ) {
v=father[u];
w=match[v];
match[u]=v;
match[v]=u;
} }
bool find_aug( int start ) {
for ( int i=1; i<=n; i++ ) father[base[i]=i]=inque[i]=0;
que[head=tail=inque[start]=1]=start;
while ( head<=tail )
for ( int u=pop(),v=1; v<=n; v++ )
if ( g[u][v] && base[v]!=base[u] && match[v]!=u ) { if ( v==start || (match[v]&&father[match[v]]) )
contract(u,v); //out-point
else if ( father[v]==0 ) { // not in-point if ( match[v] ) {
push(match[v]);
father[v]=u;
} else { father[v]=u;
augment(v);
return 1;
} } } return 0;
}
int main() {
int a,b,i,ans=0;
scanf("%d",&n);
while ( ~scanf("%d%d",&a,&b) ) g[a][b]=g[b][a]=1;
for ( i=1; i<=n; i++ )
if ( !match[i] && find_aug(i) ) ans++;
printf("%d\n",ans*2);
for ( i=1; i<=n; i++ )
if ( i<match[i] ) printf("%d %d\n",i,match[i]);
}
2.7 ManhattanMST
// by shik
#include <cstdio>
#include <algorithm>
#define N 200010 using namespace std;
struct P { int x,y,z,w,id; } p[N];
inline int dis( const P &a, const P &b ) { return abs(a.x-b.
x)+abs(a.y-b.y); }
inline bool cpx( const P &a, const P &b ) { return a.x!=b.x?
a.x>b.x:a.y>b.y; }
inline bool cpz( const P &a, const P &b ) { return a.z<b.z;
}
struct E { int a,b,c; } e[8*N];
bool operator <( const E &a, const E &b ) { return a.c<b.c;
}
struct Node { int L,R,key; } node[4*N];
int n,m,s[N];
int F( int x ) { return s[x]==x?x:s[x]=F(s[x]); } void U( int a, int b ) { s[F(b)]=F(a); }
void init( int id, int L, int R ) { node[id]=(Node){L,R,-1};
if ( L==R ) return;
init(id*2,L,(L+R)/2);
init(id*2+1,(L+R)/2+1,R);
}
void ins( int id, int x ) {
if ( node[id].key==-1 || p[node[id].key].w>p[x].w ) node[
id].key=x;
if ( node[id].L==node[id].R ) return;
if ( p[x].z<=(node[id].L+node[id].R)/2 ) ins(id*2,x);
else ins(id*2+1,x);
}
int Q( int id, int L, int R ) {
if ( R<node[id].L || L>node[id].R ) return -1;
if ( L<=node[id].L && node[id].R<=R ) return node[id].key;
int a=Q(id*2,L,R),b=Q(id*2+1,L,R);
if ( b==-1 || (a!=-1&&p[a].w<p[b].w) ) return a;
else return b;
}
void calc() { int i,j,k,cnt;
for ( i=0; i<n; i++ ) { p[i].z=p[i].y-p[i].x;
p[i].w=p[i].x+p[i].y;
}
sort(p,p+n,cpz);
for ( i=cnt=0; i<n; i=j ) {
for ( j=i+1; p[j].z==p[i].z; j++ );
for ( k=i,cnt++; k<j; k++ ) p[k].z=cnt;
}
init(1,1,cnt);
sort(p,p+n,cpx);
for ( i=0; i<n; i++ ) { j=Q(1,p[i].z,cnt);
if ( j!=-1 ) e[m++]=(E){p[i].id,p[j].id,dis(p[i],p[j])};
ins(1,i);
} }
long long MST() { long long r=0;
sort(e,e+m);
for ( int i=0; i<m; i++ ) {
if ( F(e[i].a)==F(e[i].b) ) continue;
U(e[i].a,e[i].b);
r+=e[i].c;
}
return r;
}
int main() {
int i;
scanf("%*d%*d%d",&n);
for ( i=0; i<n; i++ ) {
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id=s[i]=i;
} calc();
for ( i=0; i<n; i++ ) p[i].y=-p[i].y;
calc();
for ( i=0; i<n; i++ ) swap(p[i].x,p[i].y);
calc();
for ( i=0; i<n; i++ ) p[i].x=-p[i].x;
calc();
printf("%I64d\n",MST());
return 0;
}
2.8 PartitionTree
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define addr(l,r) (((l)+(r))|((l)!=(r))) const int maxn=210000,maxm=2200000;
int lnum[maxm],lt[maxn],rt[maxn];
struct st { int v,id; } a[maxm],s[maxn];
bool cp( st a, st b ) { return a.v<b.v; } int tt;
void init( int l, int r, int st ) { int mid=(l+r)/2,idx=addr(l,r);
if ( l==r ) { a[st]=s[l]; return; } lt[idx]=tt;
rt[idx]=tt+mid-l+1;
tt+=r-l+1;
init(l,mid,lt[idx]);
init(mid+1,r,rt[idx]);
int i=lt[idx],j=rt[idx],k=st,t=0;
while ( k<st+r-l+1 )
if ( j==rt[idx]+r-mid || (t<mid-l+1&&a[i].id<a[j].id) ) {
a[k]=a[i++];
lnum[k++]=++t;
} else { a[k]=a[j++];
lnum[k++]=t;
} }
int ask( int l, int r, int ls, int rs, int k, int st ) { int mid=(l+r)/2;
if ( l==r ) return a[st].v;
int i=(ls>0?lnum[st+ls-1]:0),j=lnum[st+rs];
if ( j-i>=k ) return ask(l,mid,i,j-1,k,lt[addr(l,r)]);
else return ask(mid+1,r,ls-i,rs-j,k-(j-i),rt[addr(l,r)]);
}
int main() {
int n,m,i,j,k;
scanf("%d%d",&n,&m);
for ( i=0; i<n; i++ ) { scanf("%d",&s[i].v);
s[i].id=i;
}
sort(s,s+n,cp);
tt=n; init(0,n-1,0);
while ( m-- ) {
scanf("%d%d%d",&i,&j,&k); i--; j--;
printf("%d\n",ask(0,n-1,i,j,k,0));
}
return 0;
}
2.9 Hopcroft
int n,m,dis[N],mx[N],my[N];
vector<int> e[N];
bool BFS() { queue<int> q;
for ( int i=1; i<=n; i++ ) if ( mx[i] ) dis[i]=INF;
else { dis[i]=0; q.push(i); } dis[0]=INF;
while ( !q.empty() && dis[0]==INF ) { int p=q.front(); q.pop();
FOR(it,e[p]) if ( dis[my[*it]]==INF ) { dis[my[*it]]=dis [p]+1; q.push(my[*it]); }
}
return dis[0]!=INF;
}
bool go( int p ) {
FOR(it,e[p]) if ( dis[my[*it]]==dis[p]+1 && (!my[*it]||go(
my[*it])) ) { mx[p]=*it; my[*it]=p; return 1; } dis[p]=INF;
return 0;
}
int main() {
int p,a,b,ans=0;
scanf("%d%d%d",&n,&m,&p);
while ( p-- ) { scanf("%d%d",&a,&b);
e[a].push_back(b);
}
while ( BFS() ) for ( int i=1; i<=n; i++ ) if ( !mx[i] &&
go(i) ) ans++;
printf("%d\n",ans);
return 0;
}
2.10 MiinmumEnclosingCircle
// expect O(N), randomize !!
// zju1450, ntuj1032
#include <cstdio>
#include <cmath>
#include <algorithm>
#define eps 1e-7
// eps-d’-211--d’-112--˛e-110--´z-179--˚u-124--Ä-234--´s-188-- ˛a -65--š-113--t’-250--ˇn-79--˛e-93--ˇn-176--˛e-98--d’-241--ÿ
-251--ł-186--ˇn-79--ˇe-173--d’-232--´z-76--´n-225--ł-186--ł -70--˛e-232-
using namespace std;
#define N 100010
struct P { double x,y; } p[N],q[3];
double dis2( P a, P b ) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.
y)*(a.y-b.y); }
P operator -( P a, P b ) { return (P){a.x-b.x,a.y-b.y}; } P operator +( P a, P b ) { return (P){a.x+b.x,a.y+b.y}; } P operator /( P a, double b ) { return (P){a.x/b,a.y/b}; } double abs2( P a ) { return a.x*a.x+a.y*a.y; }
double dot( P a, P b ) { return a.x*b.x+a.y*b.y; } double X( P a, P b ) { return a.x*b.y-a.y*b.x; } double X( P a, P b, P c ) { return X(b-a,c-a); } struct C {
P o; double r2;
C() { o.x=o.y=r2=0; } C( P a ) { o=a; r2=0; }
C( P a, P b ) { o=(a+b)/2; r2=dis2(o,a); } C( P a, P b, P c ) {
double i,j,k,A=2*X(a,b,c)*X(a,b,c);
i=abs2(b-c)*dot(a-b,a-c);
j=abs2(a-c)*dot(b-a,b-c);
k=abs2(a-b)*dot(c-a,c-b);
o.x=(i*a.x+j*b.x+k*c.x)/A;
o.y=(i*a.y+j*b.y+k*c.y)/A;
r2=dis2(o,a);
}
bool cover( P a ) { return dis2(o,a)<=r2+eps; } };
C MEC( int n, int m ) { C mec;
if ( m==1 ) mec=C(q[0]);
else if ( m==2 ) mec=C(q[0],q[1]);
else if ( m==3 ) return C(q[0],q[1],q[2]);
for ( int i=0; i<n; i++ ) if ( !mec.cover(p[i]) ) {
q[m]=p[i];
mec=MEC(i,m+1);
}
return mec;
}
int main() { srand(514);
int n,i; C mec;
while( ~scanf("%d",&n)&&n ) {
for ( i=0; i<n; i++ ) scanf("%lf%lf",&p[i].x,&p[i].y);
random_shuffle(p,p+n);
mec=MEC(n,0);
printf("%.2f %.2f %.2f\n",mec.o.x,mec.o.y,sqrt(mec.r2));
}
return 0;
}
2.11 PolyMul
void mul( int n, ULL *x, ULL *y, ULL *z ) { if ( n<=16 ) {
for ( int i=0; i<n; i++ ) for ( int j=0; j<n; j++ )
z[i+j]+=x[i]*y[j];
return;
}
int n1=n/2,n2=n-n/2,i;
vector<ULL> ac(2*n2,0),bd(2*n2,0),apb(n2,0),cpd(n2,0);
ULL *a=x,*b=x+n1,*c=y,*d=y+n1;
for ( i=0; i<n1; i++ ) { apb[i]+=a[i];
cpd[i]+=c[i];
}
for ( i=0; i<n2; i++ ) { apb[i]+=b[i];
cpd[i]+=d[i];
}
mul(n1,a,c,&ac[0]);
mul(n2,b,d,&bd[0]);
mul(n2,&apb[0],&cpd[0],z+n1);
for ( i=0; i<2*n2; i++ ) { z[i]+=ac[i];
z[2*n1+i]+=bd[i];
z[n1+i]-=ac[i]+bd[i];
} }
2.12 InervalQuery
// by shik
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 1000010
using namespace std;
int rnd() { return (rand()<<15)|rand(); } struct Q {
int L,R;
Q(){}
Q( int n ):L(rnd()%n+1),R(rnd()%n+1){ if ( L>R ) swap(L,R)
; }
Q( int _L, int _R ):L(_L),R(_R){}
} q[N];
bool cpL( Q a, Q b ) { return a.L<b.L; } bool cpR1( Q a, Q b ) { return a.R<b.R; } bool cpR2( Q a, Q b ) { return a.R>b.R; } int st,ed,xd;
void chg( int L, int R ) { xd+=abs(st-L)+abs(ed-R);
st=L; ed=R;
}
int main() {
srand(514);
int n,i,tmt;
while (~scanf("%d",&n) ) { for ( i=0; i<n; i++ ) q[i]=Q(n);
sort(q,q+n,cpL);
tmt=(int)(1.514*sqrt(n)+1);
xd=st=ed=0;
for ( i=0; i<n; i+=2*tmt ) sort(q+i,q+min(i+tmt,n),cpR1)
;
for ( i=tmt; i<n; i+=2*tmt ) sort(q+i,q+min(i+tmt,n), cpR2);
for ( i=0; i<n; i++ ) chg(q[i].L,q[i].R);
printf("xd = %d\n",xd);
}
return 0;
}
2.13 ConvexPolygonDistence
// by shik
#include <cstdio>
#include <algorithm>
#include <cmath>
#define eps 1e-5 using namespace std;
struct P { double x,y; } p0,p1[10010],p2[10010],c1[10010],c2 [10010],pa,pb;
P r( const P &a ) { return (P){a.y,-a.x}; }
P operator -( const P &a, const P &b ) { return (P){a.x-b.x, a.y-b.y}; }
bool operator <( const P &a, const P &b ) { return a.x<b.x
||(a.x==b.x&&a.y<b.y); }
double X( const P &o, const P &a, const P &b ) { return (a.x -o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y); }
double X( const P &a, const P &b ) { return a.x*b.y-b.x*a.y;
}
void convex_hull( P *p, int &n ) { int m1=0,m2=0,i;
sort(p,p+n);
for ( i=0; i<n; i++ ) {
while ( m1>=2 && X(c1[m1-2],c1[m1-1],p[i])>=0 ) m1--;
while ( m2>=2 && X(c2[m2-2],c2[m2-1],p[i])<=0 ) m2--;
c1[m1++]=c2[m2++]=p[i];
}
for ( i=n=0; i<m1; i++ ) p[n++]=c1[i];
for ( i=m2-2; i>=0; i-- ) p[n++]=c2[i];
}
double dis2( const P &a, const P &b ) { return (a.x-b.x)*(a.
x-b.x)+(a.y-b.y)*(a.y-b.y); }
double dis2( const P &a, const P &b1, const P &b2 ) { double tmp=X(r(b1-b2),b1-a)*X(r(b1-b2),b2-a);
if ( tmp<-eps ) return X(a,b1,b2)*X(a,b1,b2)/dis2(b1,b2);
else return min(dis2(a,b1),dis2(a,b2));
}
double dis2( const P &a1, const P &a2, const P &b1, const P
&b2 ) {
double t1,t2,t3,t4;
t1=X(r(b1-b2),b1-a1)*X(r(b1-b2),b2-a1);
t2=X(r(b1-b2),b1-a2)*X(r(b1-b2),b2-a2);
t3=X(r(a1-a2),a1-b1)*X(r(a1-a2),a2-b1);
t4=X(r(a1-a2),a1-b2)*X(r(a1-a2),a2-b2);
if ( t1<-eps||t2<-eps||t3<-eps||t4<-eps ) return X(a1,b1, b2)*X(a1,b1,b2)/dis2(b1,b2);
else return min(min(dis2(a1,b1),dis2(a1,b2)),min(dis2(a2, b1),dis2(a2,b2)));
}
int main() {
int n,m,i,a,b,ca,cb; double ans,tmp;
while ( scanf("%d%d",&n,&m)&&n ) {
for ( i=0; i<n; i++ ) scanf("%lf%lf",&p1[i].x,&p1[i].y);
for ( i=0; i<m; i++ ) scanf("%lf%lf",&p2[i].x,&p2[i].y);
convex_hull(p1,n);
convex_hull(p2,m);
for ( i=b=0; i<m; i++ )
if ( p2[i].x>p2[b].x||(p2[i].x==p2[b].x&&p2[i].y>p2[b ].y) ) b=i;
a=ca=cb=0; ans=tmp=1e100;
while ( ca<n && cb<m ) { pa=p1[a+1]-p1[a];
pb=p2[b+1]-p2[b];
if ( X(p0,pa,pb)>eps ) { tmp=dis2(p2[b],p1[a],p1[a+1]);
a++; ca++;
} else if ( X(p0,pa,pb)<-eps ) { tmp=dis2(p1[a],p2[b],p2[b+1]);
b++; cb++;
} else {
tmp=dis2(p1[a],p1[a+1],p2[b],p2[b+1]);
a++; b++; ca++; cb++;
}
if ( tmp<ans ) ans=tmp;
if ( a==n-1 ) a=0;
if ( b==m-1 ) b=0;
}
printf("%.5f\n",sqrt(ans));
}
return 0;
}
2.14 KM_BFS
// by shik
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <climits>
#define N 600 using namespace std;
int n,w[N][N],lx[N],ly[N],vx[N],vy[N],my[N],slk[N],fx[N],fy[
N];
void aug( int p ) { if ( p==-1 ) return;
my[p]=fy[p];
aug(fx[fy[p]]);
}
bool BFS( int p ) { queue<int> q;
q.push(p); vx[p]=1;
while ( !q.empty() ) { p=q.front(); q.pop();
for ( int i=0; i<n; i++ ) { int t=lx[p]+ly[i]-w[p][i];
if ( t>0 ) {
if ( t<slk[i] ) slk[i]=t;
continue;
}
if ( vy[i] ) continue;
vy[i]=1;
fy[i]=p;
if ( my[i]==-1 ) { aug(i);
return 1;
} else if ( !vx[my[i]] ) { vx[my[i]]=1;
fx[my[i]]=i;
q.push(my[i]);
} } }
return 0;
}
inline void gn( int &x ) { char ch;
while ( ch=getchar(),ch<’0’||ch>’9’ );
x=ch-’0’;
while ( ch=getchar(),ch>=’0’&&ch<=’9’ ) x=x*10+ch-’0’;
}
int main() {
int i,j,wx,wy,sml,ans;
while ( ~scanf("%d",&n) ) { memset(lx,0,n*sizeof(int));
memset(ly,0,n*sizeof(int));
memset(my,-1,n*sizeof(int));
ans=0;
for ( i=0; i<n; i++ ) for ( j=0; j<n; j++ ) {
gn(w[i][j]);
ans+=w[i][j];
if ( w[i][j]>lx[i] ) lx[i]=w[i][j];
}
for ( i=0; i<n; i++ ) {
for ( j=0; j<n; j++ ) slk[j]=INT_MAX;
memset(vx,0,n*sizeof(int));
memset(vy,0,n*sizeof(int));
memset(fx,-1,n*sizeof(int));
memset(fy,-1,n*sizeof(int));
wx=i;
while ( !BFS(wx) ) { sml=INT_MAX; wx=wy=-1;
for ( j=0; j<n; j++ )
if ( !vy[j] && slk[j]<sml ) sml=slk[wy=j];
for ( j=0; j<n; j++ )
if ( vx[j] && lx[j]+ly[wy]-w[j][wy]==sml ) wx=j;
for ( j=0; j<n; j++ ) { if ( vx[j] ) lx[j]-=sml;
if ( vy[j] ) ly[j]+=sml;
else slk[j]-=sml;
} } }
for ( i=0; i<n; i++ ) ans-=w[my[i]][i];
printf("%d\n",ans);
}
return 0;
}
2.15 KMP
// by shik
#include <cstdio>
using namespace std;
int main() {
int t,q,next[10010]={-1},i,j;
char T[500010],P[10010];
scanf("%d ",&t);
while ( t-- ) { gets(T);
scanf("%d ",&q);
while ( q-- ) { gets(P);
for ( i=0,j=-1; P[i]; next[++i]=++j ) while ( j>=0 && P[i]!=P[j] ) j=next[j];
for ( i=j=0; T[i]&&P[j]; i++,j++ ) while ( j>=0 && T[i]!=P[j] ) j=next[j];
puts(P[j]==0?"y":"n");
} }
return 0;
}
2.16 DLX
// by shik
#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
#define M 50000 using namespace std;
int L[M],R[M],U[M],D[M],y[M],cnt[M],e,sol;
void del( int p ) { L[R[p]]=L[p];
R[L[p]]=R[p];
for ( int i=D[p]; i!=p; i=D[i] ) { for ( int j=R[i]; j!=i; j=R[j] ) {
U[D[j]]=U[j];
D[U[j]]=D[j];
cnt[y[j]]--;
} } }
void res( int p ) {
for ( int i=U[p]; i!=p; i=U[i] )
for ( int j=L[i]; j!=i; j=L[j] ) cnt[y[U[D[j]]=D[U[j]]=j ]]++;
L[R[p]]=R[L[p]]=p;
}
void go( int lv ) { if ( lv>=sol ) return;
if ( R[0]==0 ) { sol=min(lv,sol); return; } int i,j,w=R[0];
for ( i=R[0]; i; i=R[i] ) if ( cnt[i]<cnt[w] ) w=i;
del(w);
for ( i=D[w]; i!=w; i=D[i] ) {
for ( j=R[i]; j!=i; j=R[j] ) del(y[j]);
go(lv+1);
for ( j=L[i]; j!=i; j=L[j] ) res(y[j]);
} res(w);
}
void add( int m ) { cnt[y[e]=++m]++;
U[e]=U[D[e]=m];
D[U[e]]=U[D[e]]=e;
e++;
}
void add( vector<int> &v ) { int i,t=v.size();
for ( i=0; i<t; i++ ) L[e+(i+1)%t]=R[e+(i+t-1)%t]=e+i;
for ( vector<int>::iterator it=v.begin(); it!=v.end(); it ++ ) add(*it);
}
int main() {
int i,j,t,n,m;
scanf("%d%d",&n,&m); e=m+1;
for ( i=0; i<e; i++ ) { L[i]=(i-1+e)%e;
R[i]=(i+1+e)%e;
U[i]=D[i]=i;
}
for ( i=0; i<n; i++ ) { vector<int> v;
for ( j=0; j<m; j++ ) { scanf("%d",&t);
if ( t ) v.push_back(j);
} add(v);
}
sol=n; go(0);
printf("%d\n",sol);
return 0;
}
2.17 EMST
#include <iostream>
#include <cmath>
using namespace std;
#define Oi(e) ((e)->oi)
#define Dt(e) ((e)->dt)
#define On(e) ((e)->on)
#define Op(e) ((e)->op)
#define Dn(e) ((e)->dn)
#define Dp(e) ((e)->dp)
#define Other(e, p) ((e)->oi == p ? (e)->dt : (e)->oi)
#define Next(e, p) ((e)->oi == p ? (e)->on : (e)->dn)
#define Prev(e, p) ((e)->oi == p ? (e)->op : (e)->dp)
#define V(p1, p2, u, v) (u = p2->x - p1->x, v = p2->y - p1->
y)
#define C2(u1, v1, u2, v2) (u1 * v2 - v1 * u2)
#define C3(p1, p2, p3) ((p2->x - p1->x) * (p3->y - p1->y) - (p2->y - p1->y) * (p3->x - p1->x))
#define Dot(u1, v1, u2, v2) (u1 * u2 + v1 * v2)
#define MAXN 100001 struct point {
int x, y;
struct edge *in;
bool operator < (const point &p1) const { return x < p1.x || (x == p1.x && y < p1.y);
} };
struct edge { point *oi, *dt;
edge *on, *op, *dn, *dp;
};
struct gEdge { int u, v;
double w;
bool operator < (const gEdge &e1) const {return w < e1.w
;}
}E[3 * MAXN], MST[MAXN];
int N, M;
int f[MAXN];
void Init() { for(int i = 0; i < N; ++i) f[i] = i; } int Find(int x) { return f[x]==x?x:f[x]=Find(f[x]); } void Make(int x, int y) { f[Find(y)]=Find(x); } void Kruskal() {
double length = 0.0;
Init();
sort(E, E + M);
for(int i = 0, k = 0; i < M && k < N - 1; ++i) { if(Find(E[i].u) != Find(E[i].v)) {
Make(E[i].u, E[i].v); MST[k++] = E[i]; length +=
E[i].w;
}
}
printf("%.2f\n", length);
}
point p[MAXN], *Q[MAXN];
edge mem[3 * MAXN], *elist[3 * MAXN];
int nfree;
void Alloc_memory() { nfree = 3 * N;
edge *e = mem;
for(int i = 0; i < nfree; ++i) elist[i] = e++;
}
void Splice(edge *a, edge *b, point *v) { edge *next;
if(Oi(a) == v) next = On(a), On(a) = b;
else next = Dn(a), Dn(a) = b;
if(Oi(next) == v) Op(next) = b;
else Dp(next) = b;
if(Oi(b) == v) On(b) = next, Op(b) = a;
else Dn(b) = next, Dp(b) = a;
}
edge *Make_edge(point *u, point *v) { edge *e = elist[--nfree];
e->on = e->op = e->dn = e->dp = e; e->oi = u; e->dt = v;
if(u->in == NULL) u->in = e; if(v->in == NULL) v->in = e
; return e;
}
edge *Join(edge *a, point *u, edge *b, point *v, int side) { edge *e = Make_edge(u, v);
if(side == 1) {
if(Oi(a) == u) Splice(Op(a), e, u);
else Splice(Dp(a), e, u);
Splice(b, e, v);
} else {
Splice(a, e, u);
if(Oi(b) == v) Splice(Op(b), e, v);
else Splice(Dp(b), e, v);
}
return e;
}
void Remove(edge *e) {
point *u = Oi(e), *v = Dt(e);
if(u->in == e) u->in = e->on; if(v->in == e) v->in = e->
dn;
if(Oi(e->on) == u) e->on->op = e->op;
else e->on->dp = e->op;
if(Oi(e->op) == u) e->op->on = e->on;
else e->op->dn = e->on;
if(Oi(e->dn) == v) e->dn->op = e->dp;
else e->dn->dp = e->dp;
if(Oi(e->dp) == v) e->dp->on = e->dn;
else e->dp->dn = e->dn;
elist[nfree++] = e;
}
void Make_Graph() {
for(int i = 0; i < N; ++i) { point *u = &p[i];
edge *start = u->in, *e = u->in;
do {
point *v = Other(e, u);
if(u < v) {
E[M].u = u - p, E[M].v = v - p;
E[M++].w = hypot(u->x - v->x, u->y - v->y);
}
e = Next(e, u);
} while(e != start);
} }
void Low_tangent(edge *e_l, point *o_l, edge *e_r, point * o_r, edge **l_low, point **OL, edge **r_low, point **OR ) {
point *d_l = Other(e_l, o_l), *d_r = Other(e_r, o_r);
while(true) {
if(C3(o_l, o_r, d_l) < 0.0) { e_l = Prev(e_l, d_l);
o_l = d_l; d_l = Other(e_l, o_l);
}
else if(C3(o_l, o_r, d_r) < 0.0) { e_r = Next(e_r, d_r);
o_r = d_r; d_r = Other(e_r, o_r);
}
else break;
}
*OL = o_l, *OR = o_r;
*l_low = e_l, *r_low = e_r;
}
void Merge(edge *lr, point *s, edge *rl, point *u, edge **
tangent) {
double l1, l2, l3, l4, r1, r2, r3, r4, cot_L, cot_R, u1, v1, u2, v2, N1, cot_N, P1, cot_P;
point *O, *D, *OR, *OL;
edge *B, *L, *R;
Low_tangent(lr, s, rl, u, &L, &OL, &R, &OR);
*tangent = B = Join(L, OL, R, OR, 0);
O = OL, D = OR;
do {
edge *El = Next(B, O), *Er = Prev(B, D), *next, * prev;
point *l = Other(El, O), *r = Other(Er, D);
V(l, O, l1, l2); V(l, D, l3, l4); V(r, O, r1, r2); V (r, D, r3, r4);
double cl = C2(l1, l2, l3, l4), cr = C2(r1, r2, r3, r4);
bool BL = cl > 0.0, BR = cr > 0.0;
if(!BL && !BR) break;
if(BL) {
doubledl = Dot(l1, l2, l3, l4);
cot_L = dl / cl;
do{
next = Next(El, O);
V(Other(next, O), O, u1, v1); V(Other(next, O), D, u2, v2);
N1 = C2(u1, v1, u2, v2);
if(!(N1 > 0.0)) break;
cot_N = Dot(u1, v1, u2, v2) / N1;
if(cot_N > cot_L) break;
Remove(El);
El = next;
cot_L = cot_N;
} while(true);
} if(BR) {
doubledr = Dot(r1, r2, r3, r4);
cot_R = dr / cr;
do{
prev = Prev(Er, D);
V(Other(prev, D), O, u1, v1); V(Other(prev, D), D, u2, v2);
P1 = C2(u1, v1, u2, v2);
if(!(P1 > 0.0)) break;
cot_P = Dot(u1, v1, u2, v2) / P1;
if(cot_P > cot_R) break;
Remove(Er);
Er = prev;
cot_R = cot_P;
} while(true);
}
l = Other(El, O); r = Other(Er, D);
if(!BL || (BL && BR && cot_R < cot_L)) { B = Join(B, O, Er, r, 0); D = r; }
else { B = Join(El, l, B, D, 0); O = l; } } while(true);
}
void Divide(int s, int t, edge **L, edge **R) { edge *a, *b, *c, *ll, *lr, *rl, *rr, *tangent;
int n = t - s + 1;
if(n == 2) *L = *R = Make_edge(Q[s], Q[t]);
else if(n == 3) {
a = Make_edge(Q[s], Q[s + 1]), b = Make_edge(Q[s + 1], Q[t]);
Splice(a, b, Q[s + 1]);
double v = C3(Q[s], Q[s + 1], Q[t]);
if(v > 0.0) {
c = Join(a, Q[s], b, Q[t], 0);
*L = a; *R = b;
}
else if(v < 0.0) {
c = Join(a, Q[s], b, Q[t], 1);
*L = c; *R = c;
}
else { *L = a; *R = b; } }
else if(n > 3) {
int split = (s + t) / 2;
Divide(s, split, &ll, &lr); Divide(split + 1, t, &rl , &rr);
Merge(lr, Q[split], rl, Q[split + 1], &tangent);
if(Oi(tangent) == Q[s]) ll = tangent;
if(Dt(tangent) == Q[t]) rr = tangent;
*L = ll; *R = rr;
} }
int main() {
while(scanf("%d", &N) != EOF) {
if(N == 1) {
printf("0.00\n");
continue;
}
Alloc_memory();
for(int i = 0; i < N; ++i) {
scanf("%d %d", &p[i].x, &p[i].y);
p[i].in = NULL;
}
sort(p, p + N);
for(int i = 0; i < N; i++) Q[i] = p + i;
edge *L, *R;
Divide(0, N - 1, &L, &R);
M = 0;
Make_Graph();
Kruskal();
}
return 0;
}
2.18 ReadDouble
inline void gn( double &x ) { char c;
while ( ~(c=getchar()) && (c<’0’||c>’9’)&&c!=’-’&&c!=’.’ )
; int flg=1;
if ( c==’-’ ) flg=-1,x=0;
else x=c-’0’;
while ( ~(c=getchar()) && c>=’0’ && c<=’9’ ) x=x*10+c-’0’;
if ( c!=’.’ ) return;
double p=1;
while ( ~(c=getchar()) && c>=’0’ && c<=’9’ ) { x=x*10+c-’0’;
p*=10;
} x/=p;
}
2.19 LinearInverse
inv[1] = 1;
for ( int i=2; i<N; i++ ) inv[i] = inv[MOD%i]*(MOD-MOD/i)%
MOD;
2.20 HarmonicNumber
// by shik
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
double har[200];
const double hc=0.577215664901532860606512090082;
double f( double n ) {
if ( n<200 ) return har[(int)n];
return log(n) + hc + 1/(2*n) - 1/(12*n*n) + 1/(120*n*n*n*n );
}
double g( int n ) { double r=0;
for ( int i=1; i<=n; i++) r+=1.0/i;
return r;
}
int main() {
int i,n;
for ( i=1; i<200; i++ ) har[i]=har[i-1]+1.0/i;
while ( ~scanf("%d",&n) ) { printf("f=%.20f\n",f(n));
printf("g=%.20f\n",g(n));
if ( f(n)==g(n) ) puts("SAME");
else printf("%.20f\n",f(n)-g(n));
}
return 0;
}
2.21 CircleUnionArea
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const double eps = 1e-08;
const double pi = 3.14159265358979;
double tau;
inline int fi (double a)
{
if (a > eps) return 1;
else if (a >= -eps) return 0;
else return -1;
}
typedef pair<double, double> interval;
inline interval redi (interval a) {
if (fi(a.first) == -1) return make_pair(a.first + tau, a .second + tau);
else return a;
}
struct circle {
double x, y, r;
circle (void) {}
circle (double x0, double y0, double r0) : x(x0), y(y0), r(r0) {}
};
inline int judge (const circle& a, const circle& b) {
double dx = b.x - a.x, dy = b.y - a.y;
double d = sqrt(dx * dx + dy * dy);
if (fi(a.r + b.r - d) <= 0) return 1;
else if (fi(a.r + d - b.r) <= 0) return 2;
else if (fi(b.r + d - a.r) <= 0) return 3;
else return 0;
}
inline interval intersect (const circle& a, const circle& b) {
double dx = b.x - a.x, dy = b.y - a.y;
double d = dx * dx + dy * dy;
double ag = atan2(dy, dx);
double tg = acos((a.r * a.r + d - b.r * b.r) / (2 * a.r
* sqrt(d)));
return redi(make_pair(ag - tg, ag + tg));
}
circle list[1010]; bool valid[1010]; int n;
const int ending = -10010;
struct rec {
double ang; int pwr;
rec (void) {}
rec (double a0, int p0) : ang(a0), pwr(p0) {}
bool operator < (const rec& a) const {
if (fi(ang - a.ang)) return fi(ang - a.ang) == -1;
else return pwr > a.pwr;
}
} key[5010]; int keymr;
inline double cal (const circle& c, double a0, double a1) {
double da = a1 - a0;
if (fi(da) == 0) return 0;
double px0 = c.x + c.r * cos(a0);
double py0 = c.y + c.r * sin(a0);
double px1 = c.x + c.r * cos(a1);
double py1 = c.y + c.r * sin(a1);
double s = c.r * c.r * (da - sin(da)) + (px0 * py1 - px1
* py0);
return s;
}
double stat (int cnt) {
keymr = 0; double res = 0;
if (valid[cnt] == false) return 0;
for (int i = 0; i < n; i++) {
if (i == cnt || valid[i] == false) continue;
int res = judge(list[cnt], list[i]);
if (res == 2) { valid[cnt] = false; return 0; } else if (res == 3) valid[i] = false;
else if (res == 0) {
interval tt = intersect(list[cnt], list[i]);
if(fi(tau - tt.second) == -1) {
key[keymr++] = rec(tt.first, 1);
key[keymr++] = rec(tau, -1);
key[keymr++] = rec(0, 1);
key[keymr++] = rec(tt.second - tau, -1);
} else {
key[keymr++] = rec(tt.first, 1);
key[keymr++] = rec(tt.second, -1);
} } }
if (keymr == 0) res = pi * list[cnt].r * list[cnt].r * 2;
else {
key[keymr++] = rec(tau, ending);
sort(key, key + keymr);
int stack = 0;
res += cal(list[cnt], 0, key[0].ang);
for (int i = 0; i < keymr; i++) {
stack += key[i].pwr;
if (stack == 0) res += cal(list[cnt], key[i].ang , key[i + 1].ang);
} }
return res;
}
int main () {
tau = pi * 2.0;
int cnt; scanf("%d", &cnt), n = 0;
for (int i = 0; i < cnt; i++) { int x0, y0, r0;
scanf("%d %d %d", &x0, &y0, &r0);
if (r0) list[n++] = circle(x0, y0, r0);
}
memset(valid, true, sizeof valid);
double ans = 0;
for (int i = 0; i < n; i++) ans += stat(i);
printf("%.3f\n", ans * 0.5);
return 0;
}
2.22 MillerRabin
// Miller Rabin in int
#include <cstdio>
using namespace std;
bool p[1000000];
const int ps[]={2,7,61},pk=3;
void make_p() { int i,j;
for ( i=3; i<1000; i+=2 ) if ( !p[i] )
for ( j=i*i; j<1000000; j+=i+i ) p[j]=1;
}
long long pow_mod( int a, int b, int m ) { if ( b==0 ) return 1;
long long t=pow_mod(a,b/2,m);
if ( b&1 ) return t*t%m*a%m;
else return t*t%m;
}
bool Miller_Rabin( int a, int n ) { int d=n-1;
while ( d%2==0 ) d>>=1;
long long t=pow_mod(a,d,n);
if ( t==1 ) return 1;
while ( d!=n-1 && t!=n-1 ) { t=t*t%n;
d<<=1;
}
return t==n-1;
}
bool is_p( int x ) { if ( x<=1 ) return 0;
if ( x==2 ) return 1;
if ( x%2==0 ) return 0;
if ( x<1000000 ) return !p[x];
int i;
for ( i=0; i<pk; i++ )
if ( !Miller_Rabin(ps[i],x) ) return 0;
return 1;
}
int main() {
make_p();
int n,x;
scanf("%d",&n);
while ( n-- ) { scanf("%d",&x);
puts(is_p(x)?"Y":"N");
}
return 0;
}
2.23 RightTriangleConstruction
// by shik
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main() {
int n=10000000; long long i,j,a,b,c;
for ( i=1; i<=n; i++ )
for ( j=i+1; (c=j*j+i*i)<=n; j++ ) { if ( (i+j)%2==0 ) continue;
if ( __gcd(i,j)!=1 ) continue;
a=2*i*j;
b=j*j-i*i;
} return 0;
}
2.24 LineIntersection
bool is_jiao( double a, double b, double c, double d ) { return max(a,b)>=min(c,d) && max(c,d)>=min(a,b); } bool is_jiao( P a, P b, P c, P d ) {
if ( !is_jiao(a.x,b.x,c.x,d.x) ) return 0;
if ( !is_jiao(a.y,b.y,c.y,d.y) ) return 0;
if ( dir(a,b,c)*dir(a,b,d)>0 ) return 0;
if ( dir(c,d,a)*dir(c,d,b)>0 ) return 0;
return 1;
}
bool is_jiao( Ln a, Ln b ) { return is_jiao(a.p1,a.p2,b.p1,b .p2); }
P jiao( Ln a, Ln b ) { double u=X(a.p1,a.p2,b.p1);
double v=X(a.p2,a.p1,b.p2);
return (v*b.p1+u*b.p2)/(u+v);
}
2.25 KD_Tree
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define INF 514514514
#define FOR(it,c) for ( __typeof((c).begin()) it=(c).begin()
; it!=(c).end(); it++ ) using namespace std;
struct P { int x,y;
void read() { scanf("%d%d",&x,&y); } } p[N];
struct Rec {
int x1,y1,x2,y2,z;
Rec(){}
Rec( P q ):x1(q.x),y1(q.y),x2(q.x),y2(q.y){}
void read() { scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&z); } inline bool cover( const Rec &r ) const { return x1<=r.x1
&& r.x2<=x2 && y1<=r.y1 && r.y2<=y2; }
inline bool jiao( const Rec &r ) const { return !(x2<r.x1
||x1>r.x2) && !(y2<r.y1||y1>r.y2); } } rec[N];
inline bool cpz( int a, int b ) { return rec[a].z<rec[b].z;
}
inline bool cpx( int a, int b ) { return p[a].x!=p[b].x?p[a ].x<p[b].x:p[a].y<p[b].y; }
inline bool cpy( int a, int b ) { return p[a].y!=p[b].y?p[a ].y<p[b].y:p[a].x<p[b].x; }
inline int key( int id, int lv ) { return lv%2==0?p[id].x:p[
id].y; } struct KD_T {
Rec val[8*N];
bool leaf[8*N];
void pull( int id ) {
val[id].x1=min(val[id*2].x1,val[id*2+1].x1);
val[id].y1=min(val[id*2].y1,val[id*2+1].y1);
val[id].x2=max(val[id*2].x2,val[id*2+1].x2);
val[id].y2=max(val[id*2].y2,val[id*2+1].y2);
val[id].z=min(val[id*2].z,val[id*2+1].z);
}
void init( int id, int n, int *lst, int lv ) { if ( n==1 ) {
val[id]=p[lst[0]];
val[id].z=lst[0];
leaf[id]=1;
return;
}
sort(lst,lst+n,lv%2==0?cpx:cpy);
init(id*2,n/2,lst,lv+1);
init(id*2+1,n-n/2,lst+n/2,lv+1);
pull(id);
}
void del_min( int id ) { if ( leaf[id] ) {
val[id].z=INF;
return;
}
if ( val[id*2].z==val[id].z ) del_min(id*2);
else del_min(id*2+1);
pull(id);
}
void up( int id ) { do pull(id); while ( id/=2 ); } pair<int,int> Q( int id, const Rec &r ) {
if ( !r.jiao(val[id]) ) return make_pair(INF,-1);
if ( r.cover(val[id]) ) return make_pair(val[id].z,id);
return min(Q(id*2,r),Q(id*2+1,r));
} } kdt;
int n,m;
void input() { scanf("%d",&n);
for ( int i=0; i<n; i++ ) rec[i].read();
scanf("%d",&m);
for ( int i=0; i<m; i++ ) p[i].read();
}
int ans[N],lst[N],srt[N];
void build() {
for ( int i=0; i<m; i++ ) lst[i]=i;
kdt.init(1,m,lst,0);
}
void solve() {
for ( int i=0; i<n; i++ ) srt[i]=i;
sort(srt,srt+n,cpz);
for ( int i=0; i<n; i++ ) {
pair<int,int> ret=kdt.Q(1,rec[srt[i]]);
if ( ret.first==INF ) continue;
kdt.del_min(ret.second);
kdt.up(ret.second/2);
ans[ret.first]=srt[i]+1;
}
for ( int i=0; i<m; i++ ) printf("%d\n",ans[i]);
}
int main() {
input();
build();
solve();
return 0;
}
2.26 FarthestPointPair
// by shik
#include <cstdio>
#include <algorithm>
#define dis(a,b) ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)) using namespace std;
struct P { int x,y; } p[50010],p0,pi,pj;
int X( const P &o, const P &a, const P &b ) { return (a.x-o.
x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y); }
bool operator< ( const P &a, const P &b ) { return a.x!=b.x?
a.x<b.x:a.y<b.y; } void convex_hull( int &n ) {
int i,j,m1=0,m2=0; P c1[n],c2[n];
sort(p,p+n);
for ( i=0; i<n; i++ ) {
while ( m1>=2 && X(c1[m1-2],c1[m1-1],p[i])>=0 ) m1--;
while ( m2>=2 && X(c2[m2-2],c2[m2-1],p[i])<=0 ) m2--;
c1[m1++]=c2[m2++]=p[i];
}
for ( i=0; i<m1; i++ ) p[i]=c1[i];
for ( j=m2-2; j>=0; j-- ) p[i++]=c2[j];
n=i;
//for ( i=0; i<n; i++ ) printf("(%d,%d)\n",p[i].x,p[i].y);
}
int main() {
int n,i,j,ci=0,cj=0,ans=0;
scanf("%d",&n);
for ( i=0; i<n; i++ ) scanf("%d%d",&p[i].x,&p[i].y);
convex_hull(n);
if ( n==2 ) { printf("%d\n",dis(p[0],p[1])); return 0; } for ( i=j=0; i<n; i++ )
if ( p[i].x>p[j].x ) j=i; //if ( p[i].y>p[j].y || (p[i].
y==p[j].y&&p[i].x<p[j].x) ) j=i;
//printf("j = %d\n",j);
i=1; j=0;
while ( ci<n && cj<n ) {
//printf("==(%d,%d) (%d,%d)\n",p[i].x,p[i].y,p[j].x,p[j ].y);
if ( dis(p[i],p[j])>ans ) ans=dis(p[i],p[j]);
pi=(P){p[i+1].x-p[i].x,p[i+1].y-p[i].y};
pj=(P){p[j+1].x-p[j].x,p[j+1].y-p[j].y};
if ( X(p0,pi,pj)<0 ) { j++; cj++; } else { i++; ci++; }
}
printf("%d\n",ans);
return 0;
}
2.27 Splay_Seq
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define keytree ch[ch[root][1]][0]
using namespace std;
int num[N];
struct Splay {
int val[N],sz[N],ro[N],ch[N][2],pre[N],root,top,lst[N],tmt
;
void new_node( int &x, int c ) { x=++top;
ch[x][0]=ch[x][1]=pre[x]=ro[x]=0;
sz[x]=1;
val[x]=c;
}
void build( int &x, int L, int R, int f ) { if ( L>R ) return;
int M=(L+R)/2;
new_node(x,num[M]);
build(ch[x][0],L,M-1,x);
build(ch[x][1],M+1,R,x);
pre[x]=f;
update(x);
}
void init( int n ) {
ch[0][0]=ch[0][1]=pre[0]=sz[0]=ro[0]=root=top=0;
new_node(root,-1);
new_node(ch[root][1],-1);
pre[ch[root][1]]=root;
sz[root]=2;
for ( int i=1; i<=n; i++ ) num[i]=i;
build(keytree,1,n,ch[root][1]);
update(ch[root][1]);
update(root);
}
void reverse_node( int x ) { if ( x==0 ) return;
swap(ch[x][0],ch[x][1]);
ro[x]^=1;
}
void push_down( int x ) { if ( x==0 ) return;
if ( ro[x] ) {
reverse_node(ch[x][0]);
reverse_node(ch[x][1]);
ro[x]^=1;
} }
void update( int x ) { if ( x==0 ) return;
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
}
void rotate( int x, int c ) { int y=pre[x];
push_down(y); push_down(x);
ch[y][!c]=ch[x][c];
if ( ch[x][c] ) pre[ch[x][c]]=y;
pre[x]=pre[y];
if ( pre[y] ) ch[pre[y]][ch[pre[y]][1]==y]=x;
ch[x][c]=y; pre[y]=x;
update(y); update(x);
if ( y==root ) root=x;
}
void splay( int x, int f ) { while ( pre[x]!=f ) {
if ( pre[pre[x]]==f ) rotate(x,ch[pre[x]][0]==x);
else {
int y=pre[x],z=pre[y],c=(ch[z][1]==y);
if ( ch[y][c]==x ) rotate(y,!c);
else rotate(x,c);
rotate(x,!c);
} }
if ( f==0 ) root=x;
}
void select( int k, int f ) { int x=root; k++;
while ( 1 ) { push_down(x);
if ( k==sz[ch[x][0]]+1 ) break;
if ( k<=sz[ch[x][0]] ) x=ch[x][0];
else {
k-=sz[ch[x][0]]+1;
x=ch[x][1];
} }
splay(x,f);
}
void reverse( int a, int b ) { select(a-1,0);
select(b+1,root);
reverse_node(keytree);
}