第n次考試
題目:
1.堆方塊
【題目描述】
給定N個方塊,排成一行,將它們編號1到N。
再給出P個操作:
M i j表示將i所在的那一堆移到j所在那一堆的頂上。
C i表示一個詢問,詢問i下面有多少個方塊。
你需要寫一個程序來完成這些操作。
【輸入文件】
第一行一個整數P。
接下來P行,每行一個操作。
【輸出文件】
若幹行,對應每個詢問的答案。
【樣例輸入】
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
【樣例輸出】
1
0
2
【數據規模】
對於100%的數據 1<=P<=100000,1<=i,j<=N,1<=N<=30000
2.點的數目
【題目描述】
在一維數軸上有N個正整數點,以1..N進行編號。某些點比較特殊,稱之為“怪點”。給定M段區間,每段區間有且僅有一個“怪點”。請根據這M個區間,推斷出總共有多少個“怪點”。如果推斷不出來,則輸出-1。
【輸入格式】
第一行為N和M。緊接著的M行,每行代表一個區間。
【輸出格式】
怪點的數目。推斷不出,則輸出-1。
【輸入樣例】
5 3
1 4
2 5
3 4
【輸出樣例】
1
【樣例解釋】
由第3段區間知道,點3或點4為怪點,而第1,2段區間恰好包括了點3或點4。
【數據範圍】
30%的數據,1<=N<=1000,1<=M<=200
100%數據,1 <= N <= 200,000,1 <= M <= 100,000
3. DORUCAK
【題目描述】
平面上y軸左邊和右邊各有一個凸多邊形。求一條直線y=Ax+B,使得將這兩個多邊形都分成面積相等的兩部分。
【輸入格式】
第一行一個整數n,表示一個凸多邊形有n個頂點;接下來的n行,每行兩個實數x,y,表示這n個頂點的坐標;這個凸多邊形在y軸左邊。
第n+2行是一個整數m,表示國一個凸多邊形有m個頂點,接下來的m行,每行兩個實數x,y,表示這m個頂點的坐標。這個凸多邊形在y軸右邊。
兩個凸多邊形的頂點都是按逆時針的順序給出,多邊形中沒有三點共線。
【輸出格式】
輸出A和B。答案保證存在,且唯一。A,B允許的誤差範圍為±0.001。
【輸入樣例1】
3
-6.000 1.000
-2.000 2.000
-5.000 6.000
5
1.000 -1.000
3.000 -2.000
6.000 0.000
4.000 3.000
1.000 2.000
【輸出樣例1】
-0.319961 1.556489
【輸入樣例2】
4
-5.000 -1.000
-3.000 -1.000
-3.000 6.000
-5.000 6.000
4
3.222 2.000
5.000 1.000
5.000 4.000
3.222 3.000
【輸出樣例2】
0.000000 2.500000
【數據範圍】
50%的數據 3≤ N,M ≤ 20, ?1000 < X < 1000, ?1000 < Y < 1000
100%的數據 3 ≤ N,M ≤ 5000 , ?1000 < X < 1000, ?1000 < Y < 1000
題解:
1.並查集,每一次合並,記錄是第幾個
2.dp+單調隊列優化
註意條件告訴我們的是:
1.i-j至少有一個奶牛
2.i-j最多有一個奶牛
然後就可以確定最大和最小的範圍
3.
計算幾何+二分
二分枚舉a,然後繼續二分枚舉b
代碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> const int N=30005; int m,f[N],d[N],last[N],x,y,sum[N]; char s[5]; int find(int x) { int x1; if (x!=f[x])x1=find(f[x]);else x1=x; if (f[f[x]]!=x)d[x]+=d[f[x]]; f[x]=x1; return x1; } int main() { freopen("cubes.in","r",stdin); freopen("cubes.out","w",stdout); scanf("%d",&m); for (int i=1;i<N;i++) { last[i]=1; f[i]=i; } while (m--) { scanf("%s%d",&s,&x); int x1=find(x); if (s[0]==‘M‘) { scanf("%d",&y); int y1=find(y); if (x1==y1)continue; f[x1]=y1; d[x1]=last[y1]; last[y1]+=last[x1]; } else printf("%d\n",d[x]); } return 0; }
#include<bits/stdc++.h> using namespace std; const int INF=2147483647,N=200010; int L[N],R[N],tr[N<<2],n,m; int Query(int node,int l,int r,int a,int b) { if(a<=0)a=1; if(a>b||b<=0)return 0; if(l>=a&&r<=b)return tr[node]; int mid=(l+r)>>1,ret=-INF; if(mid>=a)ret=Query(node<<1,l,mid,a,b); if(mid<b)ret=max(ret,Query(node<<1|1,mid+1,r,a,b)); return ret; } void Modify(int node,int l,int r,int g,int d) { if(l==r){tr[node]=d;return;} int mid=(l+r)>>1; if(mid>=g)Modify(node<<1,l,mid,g,d); else Modify(node<<1|1,mid+1,r,g,d); tr[node]=max(tr[node<<1],tr[node<<1|1]); } int main() { freopen("photo.in","r",stdin); freopen("photo.out","w",stdout); scanf("%d%d",&m,&n);m++; for(int i=1;i<=m;i++)R[i]=i-1; for(int i=1,a,b;i<=n;i++) { scanf("%d%d",&a,&b); L[b+1]=max(L[b+1],a); R[b]=min(R[b],a-1); } for(int i=2;i<=m;i++)L[i]=max(L[i],L[i-1]); for(int i=m-1;i>=1;i--)R[i]=min(R[i],R[i+1]); for(int i=1;i<m;i++) Modify(1,1,m,i,L[i]<=R[i]?Query(1,1,m,L[i],R[i])+1:-INF); printf("%d\n",max(-1,Query(1,1,m,L[m],R[m]))); return 0; }
#include<bits/stdc++.h> using namespace std; const int INF=2147483647,N=200010; int L[N],R[N],tr[N<<2],n,m; int Query(int node,int l,int r,int a,int b) { if(a<=0)a=1; if(a>b||b<=0)return 0; if(l>=a&&r<=b)return tr[node]; int mid=(l+r)>>1,ret=-INF; if(mid>=a)ret=Query(node<<1,l,mid,a,b); if(mid<b)ret=max(ret,Query(node<<1|1,mid+1,r,a,b)); return ret; } void Modify(int node,int l,int r,int g,int d) { if(l==r){tr[node]=d;return;} int mid=(l+r)>>1; if(mid>=g)Modify(node<<1,l,mid,g,d); else Modify(node<<1|1,mid+1,r,g,d); tr[node]=max(tr[node<<1],tr[node<<1|1]); } int main() { freopen("photo.in","r",stdin); freopen("photo.out","w",stdout); scanf("%d%d",&m,&n);m++; for(int i=1;i<=m;i++)R[i]=i-1; for(int i=1,a,b;i<=n;i++) { scanf("%d%d",&a,&b); L[b+1]=max(L[b+1],a); R[b]=min(R[b],a-1); } for(int i=2;i<=m;i++)L[i]=max(L[i],L[i-1]); for(int i=m-1;i>=1;i--)R[i]=min(R[i],R[i+1]); for(int i=1;i<m;i++) Modify(1,1,m,i,L[i]<=R[i]?Query(1,1,m,L[i],R[i])+1:-INF); printf("%d\n",max(-1,Query(1,1,m,L[m],R[m]))); return 0; }
#include<bits/stdc++.h> using namespace std; #define sqr(x) ((x)*(x)) const int N=10005; int n[3]; double K,B,Px,Py,Qx,Qy,X,Y,x[3][N],y[3][N],s[2]; double Xot(double x1,double y1,double x2,double y2) { return x1*y2-x2*y1; } bool Is(double x1,double y1,double x2,double y2) { double s1=Xot(x1-Qx,y1-Qy,Px-Qx,Py-Qy); double s2=Xot(Px-Qx,Py-Qy,x2-Qx,y2-Qy); if (s1*s2<=0) return false; X=(x1*s2+x2*s1)/(s1+s2); Y=(y1*s2+y2*s1)/(s1+s2); return true; } double Area(int k) { Px=-1E5;Py=K*Px+B; Qx=1E5;Qy=K*Qx+B; n[2]=0; for (int i=1;i<=n[k];i++) { if (Is(x[k][i-1],y[k][i-1],x[k][i],y[k][i])) x[2][++n[2]]=X,y[2][n[2]]=Y; if (Xot(x[k][i]-Px,y[k][i]-Py,Qx-Px,Qy-Py)>0) x[2][++n[2]]=x[k][i],y[2][n[2]]=y[k][i]; } double res=0; for (int i=2;i<n[2];i++) res+=Xot(x[2][i]-x[2][1],y[2][i]-y[2][1], x[2][i+1]-x[2][1],y[2][i+1]-y[2][1]); return abs(res); } int main() { freopen("dorucak.in","r",stdin); freopen("dorucak.out","w",stdout); for (int k=0;k<2;k++) { scanf("%d",&n[k]); for (int i=1;i<=n[k];i++) scanf("%lf%lf",&x[k][i],&y[k][i]); x[k][0]=x[k][n[k]]; y[k][0]=y[k][n[k]]; for (int i=2;i<n[k];i++) s[k]+=Xot(x[k][i]-x[k][1],y[k][i]-y[k][1] ,x[k][i+1]-x[k][1],y[k][i+1]-y[k][1]); s[k]=abs(s[k]); } double LK=-1E5,RK=1E5; while (LK+1E-5<RK) { K=(LK+RK)/2.0; double LB=-1E5,RB=1E5; while (LB+1E-5<RB) { B=(LB+RB)/2.0; if (Area(0)*2.0<=s[0])LB=B; else RB=B; } B=(LB+RB)/2.0; if (Area(1)*2.0<=s[1])LK=K; else RK=K; } printf("%.6lf %.6lf\n",K,B); return 0; }
第n次考試