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 ...
随机推荐
- Data Leakage in Machine Learning 机器学习训练中的数据泄漏
refer to: https://www.kaggle.com/dansbecker/data-leakage There are two main types of leakage: Leaky ...
- Kickstart部署之HTTP架构
原文转自:https://www.cnblogs.com/itzgr/p/10029527.html作者:木二 目录 一 准备 1.1 完整架构:Kickstart+DHCP+HTTP+TFTP+PX ...
- python 逆序按行读取文件
How to read a file in reverse order? import os def readlines_reverse(filename): with open(filename) ...
- 你的 SQL 还在回表查询吗?快给它安排覆盖索引
什么是回表查询 小伙伴们可以先看这篇文章了解下什么是聚集索引和辅助索引:Are You OK?主键.聚集索引.辅助索引,简单回顾下,聚集索引的叶子节点包含完整的行数据,而非聚集索引的叶子节点存储的是每 ...
- Linux环境搭建及项目部署
一. VMWare安装图解 1.点击下一步 2.接受条款,下一步 3.选择安装目录,不建议有中文目录和空格目录.下一步 4.下一步 5.这两个选项根据可以爱好习惯选择,下一步 6.安装 7.完成 9. ...
- QT 4.7.3 交叉编译环境搭建
测试平台 宿主机平台:Ubuntu 12.04.4 LTS 目标机:Easy-ARM IMX283 目标机内核:Linux 2.6.35.3 交叉编译器:arm-linux-gcc 4.4.4 tsl ...
- Python习题集(十一)
每天一习题,提升Python不是问题!!有更简洁的写法请评论告知我! https://www.cnblogs.com/poloyy/category/1676599.html 题目 如果一个正整数等于 ...
- 文件流转换为url
/** * 文件流转换为url * @param {} data //文件流 */ export function getObjectURL(data) { var url = null ...
- 样式和模板快速入门Style,Template
http://www.cnblogs.com/jv9/archive/2010/04/14/1711520.html 样式(Style)和模板(Template)的定义 在Silverlight中,样 ...
- NOIP初赛:完善程序做题技巧
最近写的文章好像还很多的.那么今天我们来讨论NOIP初赛的题型--完善程序.完善程序相对是比较难的题目了.全卷100分,完善程序占了大概26分,占比非常大.如果和英语考试试卷做比较,相当于首字母填空( ...