2020.5.16-ICPC Central Europe Regional Contest 2019
作者:互联网
A. ABB
#include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) #define INF int(1e9+1) #define CL(A,I) (memset(A,I,sizeof(A))) #define DEB printf("DEB!\n"); #define D(X) cout<<" "<<#X": "<<X<<endl; #define EQ(A,B) (A+ZERO>B&&A-ZERO<B) typedef long long ll; typedef pair<ll,ll> pll; typedef vector<int> vi; typedef pair<int,int> ii; typedef vector<ii> vii; #define IN(n) int n;scanf("%d",&n); #define FOR(i, m, n) for (int i(m); i < n; i++) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define FT(m, n) FOR(k, m, n) #define aa first #define bb second void ga(int N,int *A){F(N)scanf("%d",A+i);} #define MX (1<<20) ll pw(ll n,ll k,ll MOD){ ll r(1); while(k){ if(k&1)r*=n,r%=MOD; n*=n,n%=MOD,k>>=1; } return r; } ll inv(ll a,ll MOD){return pw(a,MOD-2,MOD);} struct HSH{ int MOD,N,I[MX],F[MX],P; void ini(char*r,int M=1000000007,ll b=257){ MOD=M,N=strlen(r),P=1,*I=1,I[1]=inv(b,MOD),*F=*r; FT(2,N)I[k]=I[k-1]*ll(I[1])%MOD; FT(1,N)P=P*b%MOD,F[k]=(ll(P)*r[k]+F[k-1])%MOD; } ll get(int b,int e){if(b>e)swap(b,e);return (F[e]-ll(b?F[b-1]:0)+MOD)*I[b]%MOD;} }t,T,r,R; char s[MX]; int N,X=INF; bool isP(int b,int e){ int H=(e-b+1)/2; if((e-b+1)&1)return t.get(b,b+H)==r.get(N-1-b-H,N-1-e)&&T.get(b,b+H)==R.get(N-1-b-H,N-1-e); return t.get(b,b+H-1)==r.get(N-1-b-H,N-1-e)&&T.get(b,b+H-1)==R.get(N-1-b-H,N-1-e); } int main(void){ scanf("%d%s",&N,s); t.ini(s),T.ini(s,1e9+9,661); reverse(s,s+N),r.ini(s),R.ini(s,1e9+9,661); F(N)if(isP(i,N-1))return printf("%d\n",i),0; assert(0); return 0; }
B. Be Geeks!
#include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) #define INF int(1e9+1) #define CL(A,I) (memset(A,I,sizeof(A))) #define DEB printf("DEB!\n"); #define D(X) cout<<" "<<#X": "<<X<<endl; #define EQ(A,B) (A+ZERO>B&&A-ZERO<B) typedef long long ll; typedef pair<ll,ll> pll; typedef vector<int> vi; typedef pair<int,int> ii; typedef vector<ii> vii; #define IN(n) int n;scanf("%d",&n); #define FOR(i, m, n) for (int i(m); i < n; i++) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define FT(m, n) FOR(k, m, n) #define aa first #define bb second void ga(int N,int *A){F(N)scanf("%d",A+i);} #define LG (18) #define MX (1<<LG) #define P2(v) (!(v&(v-1))) struct RMQx{ int dp[MX][LG+2],G[MX],XX,O=-1; void ini(int*A,int n){ if(!XX++)FT(1,MX)G[k]=O+=P2(k); F(n)dp[i][0]=i; FT(1,k-(1<<k)+n+1)F(n+1-(1<<k)) if(A[dp[i][k-1]]>A[dp[i+(1<<(k-1))][k-1]]) dp[i][k]=dp[i][k-1]; else dp[i][k]=dp[i+(1<<(k-1))][k-1]; } int qy(int *A,int L,int R){ int j(G[R-L+1]); if(A[dp[L][j]]>=A[dp[R-(1<<j)+1][j]]) return dp[L][j]; return dp[R-(1<<j)+1][j]; } }R; struct RMQg{ int dp[MX][LG+2],G[MX],XX,O=-1; void ini(int *A,int n){ if(!XX++)FT(1,MX)G[k]=O+=P2(k); F(n)dp[i][0]=A[i]; FT(1,k-(1<<k)+n+1)F(n+1-(1<<k)) dp[i][k]=__gcd(dp[i][k-1],dp[i+(1<<(k-1))][k-1]); } int qy(int L,int R){ int j(G[R-L+1]); return __gcd(dp[L][j],dp[R-(1<<j)+1][j]); } }G; #define MOD 1000000007 int N,A[MX],S,g,I,x,y; bool OK(int t){ if(t==y)return 1; return G.qy(I,t)<g; } bool ok(int t){ if(t==x)return 1; return G.qy(t,I)<g; } int bs(int B,int E){ int M; while(B+3<E) if(ok(M=(B+E)>>1))B=M; else E=M-1; while(!ok(E))--E; return E; } int BS(int B,int E){ int M; while(B<E) if(OK(M=(B+E)>>1))E=M; else B=M+1; return E; } vi X,Y; #define DF(B,E) (max(B,E)-min(B,E)) int go(int b,int e){ if(b>e)return 0; x=b-1,y=e+1; I=R.qy(A,b,e); int S=0,J=I,F=I; X.clear(),Y.clear(); X.PB(I-1),Y.PB(I+1); while(J<=e)g=G.qy(I,J),J=BS(J,e+1),X.PB(J-1); J=I; while(J>=b)g=G.qy(J,I),J=bs(b-1,J),Y.PB(J+1); FT(1,(int)X.size())FOR(i,1,(int)Y.size()) S=(S+ll(A[I])*__gcd(G.qy(I,X[k]),G.qy(Y[i],I))%MOD*DF(X[k],X[k-1])%MOD*DF(Y[i],Y[i-1]))%MOD; return (ll(S)+go(b,F-1)+go(F+1,e))%MOD; } int main(void){ scanf("%d",&N),ga(N,A),R.ini(A,N),G.ini(A,N); printf("%d\n",go(0,N-1)); return 0; }
C. Bob in Wonderland
#include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <vector> using namespace std; typedef long long int ll; typedef pair<int, int> pii; #define PB push_back #define MP make_pair #define FOR(prom, a, b) for(int prom = (a); prom < (b); prom++) #define FORD(prom, a, b) for(int prom = (a); prom > (b); prom--) #define FORDE(prom, a, b) for(int prom = (a); prom >= (b); prom--) #define R1(a) do{scanf("%d", &(a));}while(0) #define R2(a, b) do{scanf("%d%d", &(a), &(b));}while(0) #define R3(a, b, c) do{scanf("%d%d%d", &(a), &(b), &(c));}while(0) #define SV(vec) do{int s_v_;scanf("%d", &(s_v_));vec.PB(s_v_);}while(0) #define MM(co, cim) memset((co), (cim), sizeof((co))) #define DEB(x) cerr << ">>> " << #x << " : " << x << endl; #define INF 1000000007 int n, from, to, res; vector<int> g[300014]; int main () { R1(n); FOR(i, 0, n - 1) { R2(from, to); --from; --to; g[from].PB(to); g[to].PB(from); } res = 0; FOR(i, 0, n) res += max((int)g[i].size() - 2, 0); printf("%d\n", res); return 0; }
D. Deep800080
#include <bits/stdc++.h> using namespace std; typedef long long int ll; typedef double ld; typedef vector<ll> vi; // push_back insert lower_bound upper_bound erase #define F(a) for ( ll i = 0; i < (ll)(a); ++i ) #define EPS (1e-8) bool eq(ld a, ld b) { return fabs(a-b) <= fabs(a+b) * EPS; } struct Pt{ ld x, y; ll flag; bool operator <(const Pt &p) const { return x < p.x-EPS || (eq(x, p.x) && y < p.y-EPS); } Pt operator+(const Pt &p){ return{x+p.x, y+p.y}; } Pt operator-(const Pt &p){ return{x-p.x, y-p.y}; } Pt operator-(){ return{-x, -y}; } Pt operator*(ld d){ return {x*d, y*d}; } Pt operator/(ld d){ return {x/d, y/d}; } friend ostream &operator<<(ostream &os, const Pt &a){ os<<a.x<<' '<<a.y; return os; } friend istream &operator>>(istream &is, Pt &a){ is>>a.x>>a.y; return is; } }; struct Line { Pt a, b; bool operator<(Line &l){ Pt v=b-a, w=l.b-l.a; return atan2(v.y, v.x) < atan2(w.y, w.x); } }; struct Cir { Pt s; ld r; Pt point(double a)const{ return {s.x+cos(a)*r, s.y+sin(a)*r}; } bool operator<(const Cir &a){ return r<a.r; } }; ld vec(Pt a, Pt b){ return a.x*b.y-a.y*b.x; } ld vec(Pt a, Pt b, Pt c){ return vec(b-a, c-a); } ld norm(Pt a){ return hypot(a.x, a.y); } ld line_point_dist(Line l, Pt p){ return fabs(vec(p-l.a, l.b-l.a)/norm(l.b-l.a)); } Pt scale_to(Pt a, ld res){ return a*res/norm(a); } Pt normal(Pt a){ ld n=norm(a); return {-a.y/n, a.x/n}; } Pt lines_intersection(Line p, Line q){ Pt v=p.b-p.a; Pt w=q.b-q.a; ld t=vec(w, p.a-q.a)/vec(v, w); return p.a+v*t; } Pt line_point_closest_point(Line a, Pt b){ return lines_intersection(a, {b, b+normal(a.b-a.a)}); } ld circle_line_distance(Cir &a, Line &b){ return max(line_point_dist(b, a.s)-a.r, 0.); } ll circle_line_intersection(Cir a, Line b, Pt &p1, Pt &p2){ if(circle_line_distance(a, b)>0)return 0; Pt dv = line_point_closest_point(b, a.s); ld d = norm(dv-a.s); ld h = sqrt(a.r*a.r-d*d); Pt n = scale_to(b.b-b.a, h); p1 = dv+n; p2 = dv-n; return 1+!(eq(p1.x, p2.x) && eq(p1.y, p2.y)); // returns the number of intersections } ll solve(ll N, ld R, Line l, vector<Cir> a){ for(Cir &p:a) p.r = R+0.00001; vector<Pt> p; F(N){ Pt q, w; ll e = circle_line_intersection(a[i], l, q, w); if(e){ q.flag = +1; w.flag = -1; p.push_back(q); p.push_back(w); } } sort(p.begin(), p.end()); //for(Pt q:p)cerr<<q<<endl; ll mx=0,s=0; for(Pt q : p){ s += q.flag; mx = max(mx, abs(s)); } return mx; } int main(){ ll N; ld R; Line l; l.a = {0, 0}; cin >> N >> R >> l.b; vector<Cir> a(N); for(Cir &p:a) cin >> p.s; ll mx=solve(N, R, l, a); //ll mx2=solve(N, R+0.00101, l, a); // safe margin //assert(mx==mx2); cout<<mx<<endl; return 0; }
E. Zeldain Garden
#include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) #define INF int(1e9+1) #define CL(A,I) (memset(A,I,sizeof(A))) #define DEB printf("DEB!\n"); #define D(X) cout<<" "<<#X": "<<X<<endl; #define EQ(A,B) (A+ZERO>B&&A-ZERO<B) typedef long long ll; typedef pair<ll,ll> pll; typedef vector<int> vi; typedef pair<int,int> ii; typedef vector<ii> vii; #define IN(n) int n;scanf("%d",&n); #define FOR(i, m, n) for (int i(m); i < n; i++) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define FT(m, n) FOR(k, m, n) #define aa first #define bb second void ga(int N,int *A){F(N)scanf("%d",A+i);} ll X,N,Q,S; ll go(ll N){ if(!N)return 0; Q=sqrt(N+ZERO),S=0; for(ll i=1;i<=Q;++i)S+=N/i; return ll(S*__int128(2)-__int128(Q)*Q); } int main(void){ scanf("%lld%lld",&X,&N); printf("%lld\n",go(N)-go(X-1)); return 0; }
F. Light Emitting Hindenburg
#include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) #define INF int(1e9+1) #define CL(A,I) (memset(A,I,sizeof(A))) #define DEB printf("DEB!\n"); #define D(X) cout<<" "<<#X": "<<X<<endl; #define EQ(A,B) (A+ZERO>B&&A-ZERO<B) typedef long long ll; typedef pair<ll,ll> pll; typedef vector<int> vi; typedef pair<int,int> ii; typedef vector<ii> vii; #define IN(n) int n;scanf("%d",&n); #define FOR(i, m, n) for (int i(m); i < n; i++) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define FT(m, n) FOR(k, m, n) #define aa first #define bb second void ga(int N,int *A){F(N)scanf("%d",A+i);} vi A,B; int N,K,a,o=~0; int main(void){ scanf("%d%d",&N,&K); F(N)scanf("%d",&a),A.PB(a); for(int i=1<<29;i;i>>=1){ B.clear(); for(int h:A)if(h&i)B.PB(h); if((int)B.size()>=K)A=B; } for(int h:A)o&=h; printf("%d\n",o); return 0; }
G. K==S
#include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) #define INF int(1e9+1) #define CL(A,I) (memset(A,I,sizeof(A))) #define DEB printf("DEB!\n"); #define D(X) cout<<" "<<#X": "<<X<<endl; #define EQ(A,B) (A+ZERO>B&&A-ZERO<B) typedef long long ll; typedef pair<ll,ll> pll; typedef vector<int> vi; typedef pair<int,int> ii; typedef vector<ii> vii; #define IN(n) int n;scanf("%d",&n); #define FOR(i, m, n) for (int i(m); i < n; i++) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define FT(m, n) FOR(k, m, n) #define aa first #define bb second void ga(int N,int *A){F(N)scanf("%d",A+i);} #define MX (106) #define AL (26) int g[MX][AL],f[MX],E,q[MX],O[MX]; void ini(){E=1;F(AL)g[0][i]=0;CL(f,0),CL(O,0);} void add(char*s){ int L=strlen(s),u=0,c; F(L){ if(!g[u][c=s[i]-97]){ g[u][c]=E++; F(AL)g[E-1][i]=0; } u=g[u][c]; } O[u]=1; } void bld(){ int x,r,b=-1,e=0,u; F(AL)if(g[0][i])f[g[0][i]]=0,q[e++]=g[0][i]; while(++b<e)F(AL){ x=g[u=q[b]][i],r=g[f[u]][i]; if(!x)g[u][i]=r; else{ q[e++]=x,f[x]=r; O[x]|=O[r]; } } } #define MM (MX) void mul(int A[MM][MM],int B[MM][MM],int R[MM][MM],int W,int M){ F(W)FF(W)R[i][j]=0; F(W)FF(W){ ll D=M*1ll*M,S=0;; FT(0,W)if((S+=A[i][k]*1ll*B[k][j])>=D)S-=D; R[i][j]=S%M; } } void pw(int M[MM][MM],int R[MM][MM],int W,ll k,int MD){ static int E[MM][MM],H[MM][MM]; F(W)FF(W)R[i][j]=E[i][j]=i==j; while(k){ if(k&1)mul(E,M,R,W,MD),memcpy(E,R,sizeof(E)); mul(M,M,H,W,MD); memcpy(M,H,sizeof(H)); k>>=1; } } #define MOD 1000000007 ll pw(ll n,ll k){ ll r(1); while(k){ if(k&1)r*=n,r%=MOD; n*=n,n%=MOD; k>>=1; } return r; } char s[MX]; int L,N,Q,M[MX][MX],R[MX][MX]; int main(void){ scanf("%d%d",&N,&Q),ini(); F(Q){ scanf("%*d%s",s); add(s); } bld(); F(E)FF(26)if(O[g[i][j]])++M[i][E]; else ++M[i][g[i][j]]; M[E][E]=26; pw(M,R,E+1,N,MOD); printf("%lld\n",(pw(26,N)-R[0][E]+MOD)%MOD); return 0; }
H. Ponk Warshall
/** * CTU Open 2019 * Problem Solution: DNA Swaps */ #include <cassert> #include <iostream> #include <vector> #include <set> #include <map> using namespace std; int main(void) { map<char, int> letterid {{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}}; string dna1, dna2; while (cin >> dna1 >> dna2) { int len = dna1.length(); vector<vector<int>> ecnt(4, vector<int>(4)); for (int i = 0; i < len; ++i) { int l1 = letterid[dna1[i]]; int l2 = letterid[dna2[i]]; ++ecnt[l1][l2]; } int result = 0; for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) if(i != j && ecnt[i][j] >= ecnt[j][i]) { result += ecnt[j][i]; ecnt[i][j] -= ecnt[j][i]; ecnt[j][i] = 0; } for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) for (int k = 0; k < 4; ++k) { if(i == j || i == k || j == k) continue; int min = std::min(std::min(ecnt[i][j], ecnt[j][k]), ecnt[k][i]); result += 2 * min; ecnt[i][j] -= min; ecnt[j][k] -= min; ecnt[k][i] -= min; } int rest = 0; for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) if(i != j) rest += ecnt[i][j]; result += 3 * rest / 4; cout << result << endl; } return 0; }
I. Saba1000kg
#include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <vector> using namespace std; typedef long long int ll; typedef pair<int, int> pii; #define PB push_back #define MP make_pair #define FOR(prom, a, b) for(int prom = (a); prom < (b); prom++) #define FORD(prom, a, b) for(int prom = (a); prom > (b); prom--) #define FORDE(prom, a, b) for(int prom = (a); prom >= (b); prom--) #define R1(a) do{scanf("%d", &(a));}while(0) #define R2(a, b) do{scanf("%d%d", &(a), &(b));}while(0) #define R3(a, b, c) do{scanf("%d%d%d", &(a), &(b), &(c));}while(0) #define SV(vec) do{int s_v_;scanf("%d", &(s_v_));vec.PB(s_v_);}while(0) #define MM(co, cim) memset((co), (cim), sizeof((co))) #define DEB(x) cerr << ">>> " << #x << " : " << x << endl; #define INF 1000000007 int n, m, q, from, to, sqn, qs, x, u[100014], cc; vector<int> g[100014], qvec, ng[100014]; set<pii> edg; set<int> qset; pair<int, int> ge (int from, int to) { return MP(min(from, to), max(from, to)); } void go (int x) { if (u[x]) return; u[x] = 1; FOR(i, 0, (int)ng[x].size()) go(ng[x][i]); } int main () { R3(n, m, q); FOR(i, 0, m) { R2(from, to); g[from].PB(to); g[to].PB(from); edg.insert(ge(from, to)); } sqn = 1; while (sqn * sqn < n) ++sqn; FOR(qn, 0, q) { qvec.clear(); qset.clear(); R1(qs); FOR(i, 0, qs) { R1(x); qvec.PB(x); qset.insert(x); ng[x].clear(); u[x] = 0; } if (qs <= sqn) { FOR(i, 0, qs) FOR(j, i + 1, qs) { from = qvec[i]; to = qvec[j]; if (edg.count(ge(from, to))) { ng[from].PB(to); ng[to].PB(from); } } } else { FOR(i, 0, qs) FOR(j, 0, (int)g[qvec[i]].size()) { from = qvec[i]; to = g[from][j]; if (qset.count(to)) { ng[from].PB(to); ng[to].PB(from); } } } cc = 0; FOR(i, 0, qs) if (!u[qvec[i]]) { go(qvec[i]); ++cc; } printf("%d\n", cc); } return 0; }
J. Screamers in the Storm
#include <bits/stdc++.h> using namespace std; typedef long long int ll; typedef double ld; typedef vector<ll> vi; // push_back insert lower_bound upper_bound erase #define F(a) for ( ll i = 0; i < (ll)(a); ++i ) // 1e-12 is too low #define EPS (1e-10) //bool eq(ld a, ld b) { return fabs(a-b) <= fabs(a+b) * EPS; } // cannot compare very small numbers to each other bool eq(ld a, ld b) { return abs(a-b) <= EPS; } int dcmp(ld x){ return (fabs(x)<EPS) ? 0 : (x<0 ? -1 : 1); } struct Pt{ ld x, y; bool operator <(const Pt &p) const { return x < p.x-EPS || (eq(x, p.x) && y < p.y-EPS); } Pt operator+(const Pt &p){ return{x+p.x, y+p.y}; } Pt operator-(const Pt &p){ return{x-p.x, y-p.y}; } Pt operator-(){ return{-x, -y}; } Pt operator*(ld d){ return {x*d, y*d}; } Pt operator/(ld d){ return {x/d, y/d}; } friend ostream &operator<<(ostream &os, const Pt &a){ os<<a.x<<' '<<a.y; return os; } friend istream &operator>>(istream &is, Pt &a){ is>>a.x>>a.y; return is; } }; struct Line { Pt a, b; ll side; // 0=east-west, 1=north-south, 2=outside the roof bool operator<(Line &l){ Pt v=b-a, w=l.b-l.a; return atan2(v.y, v.x) < atan2(w.y, w.x); } friend ostream &operator<<(ostream &os, const Line &l){ os<<l.a<<' '<<l.b; return os; } }; ld vec(Pt a, Pt b){ return a.x*b.y-a.y*b.x; } ld vec(Pt a, Pt b, Pt c){ return vec(b-a, c-a); } ld dot(Pt a, Pt b){ return a.x*b.x+a.y*b.y; } ld norm(Pt a){ return hypot(a.x, a.y); } ld line_point_dist(Line l, Pt p){ return fabs(vec(p-l.a, l.b-l.a)/norm(l.b-l.a)); } Pt scale_to(Pt a, ld res){ return a*res/norm(a); } Pt normal(Pt a){ ld n=norm(a); return {-a.y/n, a.x/n}; } ld points_distance(Pt a, Pt b){ return norm(b-a); } ld angle2(Pt a, Pt b){ a=scale_to(a, 1); b=scale_to(b, 1); ld ang=acos(dot(a, b)); //ld ang=acos(dot(a, b)/norm(a)/norm(b)); if(ang>M_PI)ang-=2*M_PI; return ang; } ld angle(Pt a, Pt b){ ld ang=atan2(vec(a,b),dot(a,b)); if(ang>M_PI)ang-=2*M_PI; if(ang<-M_PI)ang+=2*M_PI; return ang; } Pt old_lines_intersection(Line p, Line q){ Pt v=p.b-p.a; Pt w=q.b-q.a; ld t=vec(w, p.a-q.a)/vec(v, w); return p.a+v*t; } Pt lines_intersection(Line p, Line q){ Pt v=p.b-p.a; Pt w=q.b-q.a; ld t=vec(w, p.a-q.a)/vec(v, w); Pt res=p.a+v*t; //assert(fabs((ld)0 - vec(p.a,p.b,res))<1e-2); //assert(fabs((ld)0 - vec(q.a,q.b,res))<1e-2); return res; } Pt line_point_closest_point(Line a, Pt b){ return lines_intersection(a, {b, b+normal(a.b-a.a)}); } bool is_point_on_segment(Pt p, Line s){ return dcmp(vec(s.a-p, s.b-p))==0 && dcmp(dot(s.a-p, s.b-p))<=0; } bool is_point_in_polygon_clock(Pt p, vector<Line> &lines){ for(Line &l:lines)if(is_point_on_segment(p, l))return true; ld sum = 0; for(Line &l:lines){ ld ang=angle(l.a-p, l.b-p); //cerr<<"angle: "<<ang<<endl; sum += ang; } //cerr<<"sum: "<<sum<<", eq to 0: "<<eq(sum,0)<<endl; return !eq(sum, 0); } int is_point_in_polygon(Pt p, vector<Line> &lines){ ll n=lines.size(), wn=0; for(int i=0; i<n; ++i){ Pt &p1 = lines[i].a; Pt &p2 = lines[i].b; if(is_point_on_segment(p, lines[i])) return 1;//point on the border int k = dcmp(vec(p2-p1, p-p1)); int d1 = dcmp(p1.y-p.y); int d2 = dcmp(p2.y-p.y); if(k>0 && d1<=0 && d2>0) wn++; if(k<0 && d2<=0 && d1>0) wn--; } return wn;// wn=1 point is inside, 0 outisde } bool point_is_inside2(Pt p, vector<Line> &poly){ for(Line &l:poly)if(is_point_on_segment(p, l))return true; ll r=0; p.x += EPS/2; p.y += EPS/2; for(int i=0; i<4; ++i){ ll cnt = 0; for(Line &l:poly){ if(p.y < l.a.y) if(l.a.x < p.x+EPS && p.x < l.b.x || l.b.x < p.x+EPS && p.x < l.a.x) cnt+=1; } if((cnt%2) == 0) r++; swap(p.x,p.y); p.y=-p.y; } return r<4; } bool point_is_inside(Pt p, vector<Line> &poly){ vector<bool> res; //res.push_back(point_is_inside2(p, poly)); //res.push_back(is_point_in_polygon(p, poly)); res.push_back(is_point_in_polygon_clock(p, poly)); assert(res.size()); //cerr<<"inside?: "; F(res.size())cerr<<res[i]<<' '; cerr<<endl; F(res.size()-1){ if(res[i]!=res[i+1]){ cerr<<"point is inside results: "; for(ll n:res)cerr<<n<<' '; cerr<<endl; cerr<<"and polygon:";for(Line l:poly)cerr<<" ["<<l.a<<"]"; cerr<<endl; cerr<<fixed<<setprecision(12); cerr<<"for point ["<<p<<"]\n"; cerr<<endl; //cerr<<is_point_in_polygon_clock(p, poly)<<endl; assert(res[i]==res[i+1]); } } return res[0]; } ll N, M; Line l; ld line_length, line_ang; vector<Pt> a; vector<Line> lines; void load(){ cin>>N; cin>>l.a>>l.b; Pt d=l.b-l.a; a.assign(N, {}); F(N) cin>>a[i]; lines.assign(N, {}); F(N) lines[i]={a[i], a[(i+1)%N]}; F(N) lines[i].side=eq(lines[i].a.y,lines[i].b.y); } Pt point_from_ratio(ld ratio){ return l.a*(1-ratio)+l.b*ratio; } pair<ll,ld> find_closest_side(ld ratio){ if(!(ratio>-2*EPS && ratio<1+2*EPS)){ cerr<<"ratio: "<<ratio<<endl; assert(false); } Pt center = point_from_ratio(ratio); ld dist=1e62; ll id=-1; bool inside = point_is_inside(center, lines); F(N){ Pt d1=center-lines[i].a; Pt d2=center-lines[i].b; ld d=dist; if(!inside || vec(lines[i].a, lines[i].b, center)>=-EPS){ if(d1.x==d2.x && (d1.y*d2.y<0 || min(abs(d1.y),abs(d2.y)) <= abs(d1.x))) { d=min(d, abs(d1.x)); } if(d1.y==d2.y && (d1.x*d2.x<0 || min(abs(d1.x),abs(d2.x)) <= abs(d1.y))) { d=min(d, abs(d1.y)); } } //cerr<<"point "<<center<<" is "<<d<<" close to "<<i<<endl; if(d<dist-EPS){ // strictly prefer the first found dist=d; id=i; } } assert(id!=-1); //if(ratio<0.1){ //cerr<<"closest to "<<id<<" -- ["<<center<<"] in:"<<inside<<' '<<", dist: "<<dist<<endl; //} //cerr<<"closest side to "<<center<<" is "<<id<<endl; return {inside?id:(-1-id), dist}; } struct Res{ ld ratio; ll eid, state; Pt point; Res(ld ratio, ll eid):ratio(ratio),eid(eid){ point = point_from_ratio(ratio+EPS); eid=find_closest_side(ratio).first; state = (eid<0) ? 2 : lines[eid].side; // outside is 2 } }; bool segment_intersect(Line s, Line t){ ld c1=vec(s.b-s.a, t.a-s.a), c2=vec(s.b-s.a, t.b-s.a); ld c3=vec(t.b-t.a, s.a-t.a), c4=vec(t.b-t.a, s.b-t.a); return dcmp(c1)*dcmp(c2)<EPS && dcmp(c3)*dcmp(c4)<EPS; } bool line_line_equal_dir(Line a, Line b){ return eq(0,vec(a.b-a.a, b.b-b.a)); } pair<ld,ll> bsearch(ld low, ld high, ll low_edge_id){ ld mid; //cerr<<setprecision(16); const ld max_step=0.5; while(low < high-EPS){ mid = (low+high)/2; ld step_size = line_length*(mid-low); if(step_size > max_step){ // the biggest allowed step mid = low+max_step/line_length; } //cerr<<line_length<<' '<<low<<' '<<mid<<' '<<high<<endl; ll closest_eid = find_closest_side(mid).first; //cerr<<"FIND: "<<mid<<" -> "<<closest_eid<<" vs "<<low_edge_id<<" : "<<(closest_eid!=low_edge_id)<<endl; if(closest_eid != low_edge_id) high = mid; else low = mid+EPS; } return {high, find_closest_side(high).first}; } int main(){ load(); Pt ldif=l.b-l.a; line_length=hypot(ldif.x, ldif.y); line_ang=atan2(ldif.y, ldif.x); ll first=find_closest_side(0.0).first; ll last=find_closest_side(1.0).first; if(first<0){ cerr<<"FIRST: "<<first<<endl; } assert(first>=0); if(last<0){ cerr<<"LAST: "<<last<<endl; } assert(last>=0); vector<Res> path; path.push_back({0.0, first}); ll current_eid=first; ld current_ratio=0.0; //cout<<"0\n";return 0; // build all interesting points vector<Pt> crosses; // which cross with outer lines for(Line a:lines){ if(segment_intersect(l, a)){ Pt cross_point = lines_intersection(l, a); crosses.push_back(cross_point); } } // or lie at possible roof angle for(int i=0; i<lines.size(); ++i){ // even == horiz/vert Line q=lines[i]; Pt qd=q.b-q.a; //ll sq=qd.x+qd.y; if(eq(qd.x,0))continue; for(int j=0; j<lines.size(); ++j){ // odd == vert/horiz Line w=lines[j]; Pt wd=w.b-w.a; if(eq(wd.y,0))continue; //ll sw=wd.x+wd.y; //ld dir=sw*sq>0 ? -1. : 1.; Pt origin = lines_intersection(q, w); //cerr<<"o: "<<origin<<", "<<q.a<<' '<<q.b<<' '<<w.a<<' '<<w.b<<endl; Line ne={origin, origin+Pt{1, 1}}; Line nr={origin, origin+Pt{1, -1}}; if(!line_line_equal_dir(ne, l)){ Pt cross_point = lines_intersection(ne, l); crosses.push_back(cross_point); } if(!line_line_equal_dir(nr, l)){ Pt cross_point = lines_intersection(nr, l); crosses.push_back(cross_point); } } } vector<ld> interesting_ratios; interesting_ratios.push_back(0.); interesting_ratios.push_back(1.); ld prev_ratio=-1; for(Pt cross:crosses){ ld dist=points_distance(l.a, cross); //cerr<<cross<<' '<<dist<<endl; //ld mn_ratio=(dist-1e-2) / line_length; //ld mx_ratio=(dist+1e-2) / line_length; ld ratio=dist / line_length + 3*EPS; if((abs(ratio-prev_ratio)>EPS/2) && ratio>=-EPS && ratio < 1+EPS){ interesting_ratios.push_back(ratio); prev_ratio=ratio; } } sort(interesting_ratios.begin(), interesting_ratios.end()); for(ld new_ratio : interesting_ratios){ ll new_eid = find_closest_side(new_ratio).first; path.push_back({new_ratio, new_eid}); } path.push_back({1.0, last}); ld side_sum[3]; side_sum[0]=side_sum[1]=side_sum[2]=0; // north-south, east-west, outside ll last_side=-2; F(path.size()-1){ ld dif=path[i+1].ratio-path[i].ratio; if(dif>EPS){ ld eid=path[i].eid; ld ratio=path[i].ratio; //Pt center=l.a*(1-ratio)+l.b*ratio; ll side=path[i].state; assert(side >= 0 && side <= 2); side_sum[side]+=dif; //if(last_side != side){ //cerr<<fixed<<setprecision(12); //cerr<<"add ref "<<ratio<<" to "<<side<<endl; //last_side = side; //} } } ld sum=side_sum[0]*(hypot(1, abs(cos(line_ang))))+side_sum[1]*(hypot(1, abs(sin(line_ang))))+side_sum[2]; ld res=sum*hypot(ldif.x, ldif.y); cout<<fixed<<setprecision(12); cout<<res<<endl; //cerr<<"sol: \n";F(3){ cerr<<"sum: "<<i<<": "<<side_sum[i]<<endl; } //ld sm=0;F(3)sm+=side_sum[i]; cerr<<"sumsum: "<<sm<<endl; //for(ld r:interesting_ratios){ cerr<<r<<' '; } cerr<<endl; // only for drawing testcases visual correctness check: //cout<<fixed<<setprecision(6); //for(auto p:path){ //auto pr=find_closest_side(p.ratio); ////ll id = pr.first; //ld dist = pr.second; //cout<<p.point<<' '<<max((ld)0.1,dist)<<' '<<(p.state!=2 ? p.state : -1)<<endl; //} return 0; }
K. The Bugs
#include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) #define INF int(1e9+1) #define CL(A,I) (memset(A,I,sizeof(A))) #define DEB printf("DEB!\n"); #define D(X) cout<<" "<<#X": "<<X<<endl; #define EQ(A,B) (A+ZERO>B&&A-ZERO<B) typedef long long ll; typedef pair<ll,ll> pll; typedef vector<int> vi; typedef pair<int,int> ii; typedef vector<ii> vii; #define IN(n) int n;scanf("%d",&n); #define FOR(i, m, n) for (int i(m); i < n; i++) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define FT(m, n) FOR(k, m, n) #define aa first #define bb second void ga(int N,int *A){F(N)scanf("%d",A+i);} #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; struct TP{ typedef int tp; tree<tp,null_type,less<tp>,rb_tree_tag,tree_order_statistics_node_update> T; void add(tp a){T.insert(a);} void del(tp a){T.erase(a);} int cnt(tp a){return T.order_of_key(a);} tp kth(int a){return *T.find_by_order(a);} int gt(tp b,tp e){return cnt(e+1)-cnt(b);} int sz(){return T.size();} void clr(){T.clear();} int mn(){return kth(0);} int mx(){return kth(sz()-1);} }T; #define LG (18) #define MX (1<<LG) #define P2(v) (!(v&(v-1))) struct RMQ{ int dp[LG+2][MX],XX,O=-1,G[MX]; void ini(int*A,int n){ if(!XX++)FT(1,MX)G[k]=O+=P2(k); F(n)dp[0][i]=i; FT(1,k-(1<<k)+n+1)F(n+1-(1<<k)) if(A[dp[k-1][i]]<A[dp[k-1][i+(1<<(k-1))]]) dp[k][i]=dp[k-1][i]; else dp[k][i]=dp[k-1][i+(1<<(k-1))]; } int qy(int*A,int L,int R){ const int j=G[R-L+1]; if(A[dp[j][L]]<=A[dp[j][R-(1<<j)+1]]) return A[dp[j][L]]; return A[dp[j][R-(1<<j)+1]]; } }b; struct RMQ2{ int dp[MX][LG+2],G[MX],XX,O=-1; void ini(int*A,int n){ if(!XX++)FT(1,MX)G[k]=O+=P2(k); F(n)dp[i][0]=i; FT(1,k-(1<<k)+n+1)F(n+1-(1<<k)) if(A[dp[i][k-1]]>A[dp[i+(1<<(k-1))][k-1]]) dp[i][k]=dp[i][k-1]; else dp[i][k]=dp[i+(1<<(k-1))][k-1]; } int qy(int *A,int L,int R){ int j(G[R-L+1]); if(A[dp[L][j]]>=A[dp[R-(1<<j)+1][j]]) return A[dp[L][j]]; return A[dp[R-(1<<j)+1][j]]; } }e; int N,A[MX],X[MX][5],Y[MX][5]; int nrm(int a,int b,int c){ int B[3]={a,b,c},L; sort(B,B+3),L=unique(B,B+3)-B; unordered_map<int,int> T; F(L)T[B[i]]=i+1; return 100*T[a]+10*T[b]+T[c]; } void go(int X[MX][5]){ T.clr(); FT(1,N){ T.add(A[k-1]); if(T.mn()<A[k])X[k][0]=T.mn(); if(T.mx()>A[k])X[k][4]=T.mx(); int I=T.cnt(A[k]); if(T.mx()>=A[k]&&T.kth(I)==A[k])X[k][2]=A[k]; if(T.mn()<A[k])X[k][1]=T.kth(I-1); if(T.mx()>A[k])X[k][3]=~X[k][2]?T.kth(I+1):T.kth(I); } } set<int> O; map<int,int> L; int main(void){ scanf("%d",&N),ga(N,A),CL(X,-1),CL(Y,-1),b.ini(A,N),e.ini(A,N); F(N){ if(L.count(A[i])){ if(b.qy(A,L[A[i]],i)<A[i])O.insert(212); if(e.qy(A,L[A[i]],i)>A[i])O.insert(121); } L[A[i]]=i; } go(X); reverse(A,A+N),go(Y); reverse(A,A+N); F(N/2)FF(5)swap(Y[i][j],Y[N-i-1][j]); // F(N){ // DEB // printf("%d: ",A[i]);FF(5)printf(" %d",X[i][j]);puts(""); // printf("%d: ",A[i]);FF(5)printf(" %d",Y[i][j]);puts(""); // } F(N)FF(5)if(~X[i][j])FT(0,5)if(~Y[i][k])O.insert(nrm(X[i][j],A[i],Y[i][k])); for(auto&h:O)printf("%d\n",h); return 0; }
标签:Europe,typedef,Central,16,int,ll,return,include,define 来源: https://www.cnblogs.com/mxw000120/p/12952489.html