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;
}
2020.5.16-ICPC Central Europe Regional Contest 2019的更多相关文章
- ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków
ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik’s Rect ...
- 2017-2018 ACM-ICPC, Central Europe Regional Contest (CERC 17)
A. Assignment Algorithm 按题意模拟即可. #include<stdio.h> #include<iostream> #include<string ...
- Central Europe Regional Contest 2012 Problem I: The Dragon and the Knights
一个简单的题: 感觉像计算几何,其实并用不到什么计算几何的知识: 方法: 首先对每条边判断一下,看他们能够把平面分成多少份: 然后用边来对点划分集合,首先初始化为一个集合: 最后如果点的集合等于平面的 ...
- Central Europe Regional Contest 2012 Problem c: Chemist’s vows
字符串处理的题目: 学习了一下string类的一些用法: 这个代码花的时间很长,其实可以更加优化: 代码: #include<iostream> #include<string> ...
- Central Europe Regional Contest 2012 Problem J: Conservation
题目不难,感觉像是一个拓扑排序,要用双端队列来维护: 要注意细节,不然WA到死 = =! #include<cstdio> #include<cstring> #includ ...
- Central Europe Regional Contest 2012 Problem H: Darts
http://acm.hunnu.edu.cn/online/problem_pdf/CERC2012/H.pdf HUNNU11377 题意:飞镖环有十个环,没个环从外到里对应一个得分1~10,每个 ...
- ICPC Central Russia Regional Contest (CRRC 19)题解
题目连接:https://codeforces.com/gym/102780 寒假第二次训练赛,(某菜依旧是4个小时后咕咕咕),战况还行,个人表现极差(高级演员) A:Green tea 暴力枚举即可 ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)
2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred) easy: ACE ...
- 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解
题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...
随机推荐
- docker-compose权限不够
root@kali:~# docker-compose version -bash: /usr/local/bin/docker-compose: 权限不够 chmod +x /usr/local/b ...
- Ubuntu 系统安装、配置
windows下制作安装U盘 使用工具:Universal USB Installer ubuntu下制作安装U盘 使用工具:Startup Disk Creator(自带) 选择国内源:Switch ...
- 分享几个下载豆瓣资源的chrome插件
最近chrome终于以4.69%的市场占有率击败firefox成为中国第二大浏览器.(第一当然是争霸宇宙的IE了) 虽然chrome官方应用程序商店有不少豆瓣的辅助插件,但大多没什么用.属于蛋疼插件. ...
- Springboot_Email注解爆红
应该是更新后的版本,不会自动导入pom依赖 <!--新版本需要validation启动器 --> <dependency> <groupId>org.springf ...
- JS_DOM操作之操作标签
<标签名 属性1="属性值1" 属性2="属性值2"-->文本</标签名> 1 - 文本操作 <div class="c ...
- Spring AOP Aspect的简单实现(基于注解)
第1步:声明使用注解 <!-- 配置扫描注解--> 扫描包的位置<context:component-scan base-package="com.zz"/> ...
- .net中使用JSON
在.NET使用JSON作为数据交换格式 ASP.NET中JSON的序列化和反序列化 三种方式: 使用System.Web.Script.Serialization.JavaScriptSerializ ...
- WinForm控件常用设置(转)
本来想自己整理一份,但找到了一份挺全的,就直接用到直接找吧 A0 ---- 通用A1 ---- Form 类A2 ---- Control 类A3 ---- MessageBox 类A4 ---- B ...
- Map集和
目录 Map 特点 继承树 常用方法 entrySet 方法 HashMap 特点 HashMap 的重要常量 存储结构 jdk1.8 总结 面试题 HashMap存储自定义类型键值 LinkedHa ...
- Maven项目之间关系介绍
Maven项目之间的关系 依赖关系 单纯的项目A中需要项目B中的资源,将项目B打成Jar包被A依赖,此时项目A直接调用项目B中资源即可. 项目A和项目B此时形成最基本的依赖关系. 继承关系 需要场景: ...