看CF上標籤的意思應該是2-sat+數據結構優化建圖難怪是H題c++
看了題解,其實想一想(也許)可以想出來數據結構
設兩組的最大l和最小r爲l1r1l2r2,則知足l1+l2<=t2且r1+r2>=t1優化
根據max(l)和min(r)是否在同一區間分類討論spa
判斷很簡單,設表明1和2區間的點,兩點之間有邊即不能在同一區間code
而後判是不是二分圖,以及新建的點顏色是否不一樣便可blog
最後具體分的人數要考慮一下,還要特判一下全在某個集合的和max(l)>t2的it
大概是這樣,有一點細節class
#include <bits/stdc++.h> #define fo(a,b,c) for (a=b; a<=c; a++) #define fd(a,b,c) for (a=b; a>=c; a--) #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) #define inf 2133333333 #define ll long long //#define file using namespace std; int a[600001][2],ls[100003],L[100001],R[100001],b[100001][2],f[100003],len,t1,t2,n,m,i,j,k,l,ml,mr,l1,r1,l2,r2; bool bz; void New(int x,int y) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;} void NEW(int x,int y) {New(x,y);New(y,x);} void dfs(int t) { int i; if (!bz) return; for (i=ls[t]; i; i=a[i][1]) if (!f[a[i][0]]) {f[a[i][0]]=3-f[t];dfs(a[i][0]);} else if (f[a[i][0]]==f[t]) {bz=0;return;} } void work(bool tp) { int i,j,k,l; memset(ls,0,sizeof(ls));len=0; memset(f,0,sizeof(f)); fo(i,1,m) NEW(b[i][0],b[i][1]); fo(i,1,n) if (!tp) { if (R[i]<t1-mr || R[i]<ml) NEW(n+1,i); if (L[i]>t2-ml || mr<L[i]) NEW(n+2,i); } else if (!(L[i]<=t2-ml && R[i]>=t1-mr)) NEW(n+2,i); bz=1; f[n+1]=1;dfs(n+1); if (f[n+2]==1 || !bz) return; f[n+2]=2;dfs(n+2); if (bz) { fo(i,1,n) if (!f[i]) { f[i]=1;dfs(i); if (!bz) return; } } if (bz) { printf("POSSIBLE\n"); l1=l2=-inf,r1=r2=inf; if (!tp) l1=ml,r2=mr; else l1=ml,r1=mr; fo(i,1,n) if (f[i]==1) l1=max(l1,L[i]),r1=min(r1,R[i]); else l2=max(l2,L[i]),r2=min(r2,R[i]); fo(i,1,n) if (f[i]==2) break; if (i>n) {printf("%d %d\n",l1,max(t1-l1,0));} else {k=max(l1+l2,t1);printf("%d %d\n",l1+max((k-l1)-r2,0),k-(l1+max((k-l1)-r2,0)));} fo(i,1,n) printf("%d",f[i]); printf("\n"); exit(0); } } int main() { #ifdef file freopen("CF538H.in","r",stdin); #endif scanf("%d%d",&t1,&t2); scanf("%d%d",&n,&m); ml=-inf;mr=inf; fo(i,1,n) scanf("%d%d",&L[i],&R[i]),ml=max(ml,L[i]),mr=min(mr,R[i]); fo(i,1,m) scanf("%d%d",&b[i][0],&b[i][1]); if (ml>t2) {printf("IMPOSSIBLE\n");return 0;} if (n==1) { if (L[1]<=t2 && t1<=R[1]) {printf("POSSIBLE\n");printf("%d %d\n",max(L[1],t1),0);printf("1\n");} else printf("IMPOSSIBLE\n"); return 0; } if (ml>mr) {fo(i,1,n) if (mr<L[i] && R[i]<ml) {printf("IMPOSSIBLE\n");return 0;}} work(0); if (ml<=mr) work(1); printf("IMPOSSIBLE\n"); fclose(stdin); fclose(stdout); return 0; }