• 沒有找到結果。

1.1Calculation Contents 1AdHoc

N/A
N/A
Protected

Academic year: 2022

Share "1.1Calculation Contents 1AdHoc"

Copied!
25
0
0

加載中.... (立即查看全文)

全文

(1)

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++;

(2)

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);

(3)

}

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;

(4)

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’);

(5)

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;

(6)

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

(7)

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));

(8)

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;

}

(9)

}

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) {

(10)

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 {

(11)

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);

}

(12)

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);

}

參考文獻

相關文件

fostering independent application of reading strategies Strategy 7: Provide opportunities for students to track, reflect on, and share their learning progress (destination). •

Strategy 3: Offer descriptive feedback during the learning process (enabling strategy). Where the

Now, nearly all of the current flows through wire S since it has a much lower resistance than the light bulb. The light bulb does not glow because the current flowing through it

The principal chiral model has two conserved currents corresponding to the G × G symmetry of the action.. These currents are

IQHE is an intriguing phenomenon due to the occurrence of bulk topological insulating phases with dissipationless conducting edge states in the Hall bars at low temperatures

The Hilbert space of an orbifold field theory [6] is decomposed into twisted sectors H g , that are labelled by the conjugacy classes [g] of the orbifold group, in our case

Given a connected graph G together with a coloring f from the edge set of G to a set of colors, where adjacent edges may be colored the same, a u-v path P in G is said to be a

Theorem (M.Kalkowski, M.Karonski, and F.Pfender, 2010) ([8]) Every connected graph G 6= K 2 is 5-edge weight colorable1. Theorem (T.Bartnicki, J.Grytczuk,