期末考试结束又到了做题的时候了
hdu5964
大胆推出公式,发现面积可以转换为两个互相独立的参数函数……

1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 ll a,b,c,d; 6 ll mi,mx,x,y; 7 int main() 8 { 9 int n; 10 while (scanf("%lld%lld%lld%lld",&a,&b,&c,&d)!=EOF) 11 { 12 scanf("%d",&n); 13 mi=1e20; mx=0; 14 for (int i=0; i<n; i++) 15 { 16 scanf("%lld%lld",&x,&y); 17 mi=min(mi,a*c*x*x+b*d*y*y+(a*d+b*c)*x*y); 18 mx=max(mx,a*c*x*x+b*d*y*y+(a*d+b*c)*x*y); 19 } 20 printf("%lld ",(ll)(fabs(1.0*(mx-mi)/(a*d-b*c))+0.5)); 21 } 22 return 0; 23 }
hdu3457 3458
双倍经验,先把矩形分成左下右上两个点然后一维排序,一维树状数组维护;处理时矩形两个点,一个点查询,一个点更新

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 struct node{int x,y,id;} a[200010]; 5 int b[200010],c[200010],op[200010],wh[200010],f[200010]; 6 int n; 7 8 void add(int x,int w) 9 { 10 for (int i=x; i<=2*n; i+=i&(-i)) 11 b[i]=max(b[i],w); 12 } 13 14 int ask(int x) 15 { 16 int s=0; 17 for (int i=x; i; i-=i&(-i)) 18 s=max(b[i],s); 19 return s; 20 } 21 bool cmp(node a,node b) 22 { 23 if (a.x==b.x&&a.y==b.y) return a.id<b.id; 24 if (a.x==b.x) return a.y<b.y; 25 return a.x<b.x; 26 } 27 28 int main() 29 { 30 // freopen("1.in","r",stdin); 31 scanf("%d",&n); 32 while (n) 33 { 34 for (int i=1; i<=n; i++) 35 { 36 scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i+n].x,&a[i+n].y); 37 a[i].id=i; 38 a[i+n].id=i+n; 39 b[i]=a[i].y; b[i+n]=a[i+n].y; 40 } 41 sort(a+1,a+1+2*n,cmp); 42 sort(b+1,b+1+2*n); 43 int m=1; c[1]=b[1]; 44 for (int i=2; i<=2*n; i++) if (b[i]!=b[i-1]) c[++m]=b[i]; 45 for (int i=1; i<=2*n; i++) 46 { 47 a[i].y=lower_bound(c+1,c+1+m,a[i].y)-c; 48 if (a[i].id<=n) op[a[i].id]=i; 49 } 50 for (int i=1; i<=2*n; i++) 51 if (a[i].id>n) wh[i]=op[a[i].id-n]; 52 memset(b,0,sizeof(b)); 53 int ans=0; 54 for (int i=1; i<=2*n; i++) 55 { 56 if (a[i].id<=n) 57 { 58 f[i]=ask(a[i].y-1)+1; 59 ans=max(ans,f[i]); 60 } 61 else add(a[i].y,f[wh[i]]); 62 } 63 printf("%d ",ans); 64 scanf("%d",&n); 65 } 66 }
hdu1964
插头dp的模板题练练手

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const int mo=30007; 6 const int maxl=1000010; 7 int r[15][15],d[15][15],b[15],v[15],n,m,p; 8 string s; 9 10 struct node{ 11 int p[mo],f[maxl],len,nex[maxl]; 12 ll st[maxl]; 13 void clr() 14 { 15 len=0; 16 memset(p,255,sizeof(p)); 17 } 18 void push(ll nw,int s) 19 { 20 int x=nw%mo; 21 for (int i=p[x]; i>-1; i=nex[i]) 22 if (st[i]==nw) 23 { 24 f[i]=min(f[i],s); 25 return; 26 } 27 st[++len]=nw; f[len]=s; 28 nex[len]=p[x]; p[x]=len; 29 } 30 } h[2]; 31 32 void get(ll st) 33 { 34 for (int i=m; i>=0; i--) 35 { 36 b[i]=st&7; 37 st>>=3; 38 } 39 } 40 41 ll put() 42 { 43 memset(v,255,sizeof(v)); v[0]=0; 44 ll st=0; int t=0; 45 for (int i=0; i<=m; i++) 46 { 47 if (v[b[i]]==-1) v[b[i]]=++t; 48 b[i]=v[b[i]]; 49 st<<=3; st|=b[i]; 50 } 51 return st; 52 } 53 54 void shift() 55 { 56 for (int i=m; i; i--) b[i]=b[i-1]; 57 b[0]=0; 58 } 59 60 void work(int j,int s) 61 { 62 if (j==m) shift(); 63 h[p].push(put(),s); 64 } 65 66 void dp(int i,int j) 67 { 68 for (int k=1; k<=h[p^1].len; k++) 69 { 70 get(h[p^1].st[k]); 71 int x=b[j],y=b[j-1],s=h[p^1].f[k]; 72 if (x&&y) 73 { 74 if ((x!=y)||(x==y&&i==n&&j==m)) 75 { 76 b[j]=b[j-1]=0; 77 if (x!=y) 78 for (int z=0; z<=m; z++) 79 if (b[z]==x) b[z]=y; 80 work(j,s); 81 } 82 } 83 else if ((x&&!y)||(!x&&y)) 84 { 85 int z=x+y; 86 if (j<m) 87 { 88 b[j]=z; b[j-1]=0; 89 work(j,s+r[i][j]); 90 } 91 if (i<n) 92 { 93 b[j]=0; b[j-1]=z; 94 work(j,s+d[i][j]); 95 } 96 } 97 else if (i<n&&j<m) 98 { 99 b[j]=b[j-1]=m+1; 100 work(j,s+d[i][j]+r[i][j]); 101 } 102 } 103 } 104 105 int main() 106 { 107 int cas; 108 scanf("%d",&cas); 109 while (cas--) 110 { 111 scanf("%d%d ",&n,&m); 112 memset(r,255,sizeof(r)); 113 memset(d,255,sizeof(d)); 114 for (int i=1; i<=2*n+1; i++) 115 { 116 getline(cin,s); 117 for (int j=1; j<=2*m; j++) 118 if (s[j]>='0'&&s[j]<='9') 119 { 120 if (i&1) d[i/2][(j+1)/2]=s[j]-'0'; 121 else r[i/2][(j+1)/2]=s[j]-'0'; 122 } 123 } 124 h[0].clr(); 125 h[0].push(0,0); 126 p=0; 127 for (int i=1; i<=n; i++) 128 for (int j=1; j<=m; j++) 129 { 130 // printf("%d %d ",r[i][j],d[i][j]); 131 p^=1; h[p].clr(); 132 dp(i,j); 133 } 134 printf("%d ",h[p].f[1]); 135 } 136 }
hdu5730
设f[i][j][s1][s2]表示到第i个和为j用了s1个必选,s2个必不选,每个数有必选、必不选、选、不选4种情况
注意这道题卡时

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 const int mo=1000000007; 5 int f[1005][1005][3][3],a[1010],n,s; 6 void inc(int &a,int b) 7 { 8 a+=b; 9 if (a>=mo) a-=mo; 10 } 11 12 int main() 13 { 14 int cas; 15 scanf("%d",&cas); 16 while (cas--) 17 { 18 scanf("%d%d",&n,&s); 19 memset(f,0,sizeof(f)); 20 for (int i=1; i<=n; i++) scanf("%d",&a[i]); 21 f[0][0][0][0]=1; 22 for (int i=1; i<=n; i++) 23 { 24 for (int j=0; j<=s; j++) 25 for (int s1=0; s1<=2; s1++) 26 for (int s2=0; s2<=2; s2++) 27 { 28 if (j+a[i]<=s) 29 { 30 inc(f[i][j+a[i]][s1][s2],f[i-1][j][s1][s2]); 31 if (s1<2) inc(f[i][j+a[i]][s1+1][s2],f[i-1][j][s1][s2]); 32 } 33 inc(f[i][j][s1][s2],f[i-1][j][s1][s2]); 34 if (s2<2) inc(f[i][j][s1][s2+1],f[i-1][j][s1][s2]); 35 } 36 } 37 int ans=0; 38 for (int i=0; i<=s; i++) inc(ans,f[n][i][2][2]); 39 printf("%lld ",4ll*ans%mo); 40 } 41 }
poj2699
如果有k个strong king,那么可以构造出分数k大为strong king的方案,于是枚举strong king个数经典的建图最大流判断之

1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 6 using namespace std; 7 8 struct way{int next,flow,po;} e[200010]; 9 int numh[110],h[110],cur[110],pre[110],a[110],p[110],t,n,len; 10 string s; 11 12 void add(int x,int y,int f) 13 { 14 e[++len].po=y; 15 e[len].flow=f; 16 e[len].next=p[x]; 17 p[x]=len; 18 } 19 20 void build(int x,int y,int f) 21 { 22 add(x,y,f); 23 add(y,x,0); 24 } 25 26 int sap() 27 { 28 for (int i=0; i<=t; i++) 29 { 30 cur[i]=p[i]; 31 h[i]=numh[i]=0; 32 } 33 numh[0]=t+1; 34 int u=0,s=0; 35 while (h[0]<t+1) 36 { 37 bool ff=1; 38 for (int i=cur[u]; i>-1; i=e[i].next) 39 { 40 int j=e[i].po; 41 if (e[i].flow&&h[u]==h[j]+1) 42 { 43 pre[j]=u; cur[u]=i; u=j; 44 ff=0; 45 if (u==t) 46 { 47 s++; 48 if (s==(n-1)*n/2) return s; 49 while (u) 50 { 51 u=pre[u]; 52 j=cur[u]; 53 e[j].flow--; e[j^1].flow++; 54 } 55 } 56 break; 57 } 58 } 59 if (ff) 60 { 61 if (--numh[h[u]]==0) return s; 62 int q=-1,tmp=t; 63 for (int i=p[u]; i>-1; i=e[i].next) 64 { 65 int j=e[i].po; 66 if (e[i].flow&&h[j]<tmp) 67 { 68 tmp=h[j]; 69 q=i; 70 } 71 } 72 h[u]=tmp+1; numh[h[u]]++; cur[u]=q; 73 if (u) u=pre[u]; 74 } 75 } 76 return s; 77 } 78 79 bool check(int k) 80 { 81 len=-1; memset(p,255,sizeof(p)); 82 for (int i=1; i<=n; i++) 83 build(0,i,a[i]); 84 int w=n; 85 for (int i=1; i<n; i++) 86 for (int j=i+1; j<=n; j++) 87 { 88 build(++w,t,1); 89 build(i,w,1); 90 if (!(i>n-k&&a[j]>a[i])) build(j,w,1); 91 } 92 if (sap()==n*(n-1)/2) return 1; else return 0; 93 } 94 95 int main() 96 { 97 int cas; 98 scanf("%d ",&cas); 99 while (cas--) 100 { 101 getline(cin,s); 102 int l=s.length(); 103 int i=0; n=0; 104 while (i<l) 105 { 106 int x=0,j=i; 107 for (; j<l&&s[j]!=' '; j++) x=x*10+s[j]-'0'; 108 if (s[i]>= '0'&&s[i]<= '9') a[++n]=x; 109 i=j+1; 110 } 111 t=n*(n-1)/2+n+1; 112 int ans=1; 113 for (int i=n; i; i--) 114 if (check(i)) 115 { 116 ans=i; 117 break; 118 } 119 printf("%d ",ans); 120 } 121 }
spoj287
经典的二分颜色数+最大流判定

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 7 using namespace std; 8 const int inf=100000007; 9 struct way{int po,next,flow;} e[800010]; 10 vector<int> g[510]; 11 int len,n,m,k,t,pre[510],numh[510],cur[510],h[510],d[510],p[510],a[510]; 12 13 void add(int x,int y,int f) 14 { 15 e[++len].po=y; 16 e[len].flow=f; 17 e[len].next=p[x]; 18 p[x]=len; 19 } 20 21 void build(int x, int y, int f) 22 { 23 add(x,y,f); 24 add(y,x,0); 25 } 26 27 int sap() 28 { 29 memset(h,0,sizeof(h)); 30 memset(numh,0,sizeof(numh)); 31 numh[0]=t+1; 32 for (int i=0; i<=t; i++) cur[i]=p[i]; 33 int j,u=0,s=0,neck=inf; 34 while (h[0]<t+1) 35 { 36 d[u]=neck; 37 bool ch=1; 38 for (int i=cur[u]; i!=-1; i=e[i].next) 39 { 40 j=e[i].po; 41 if (e[i].flow>0&&h[u]==h[j]+1) 42 { 43 neck=min(neck,e[i].flow); 44 cur[u]=i; 45 pre[j]=u; u=j; 46 if (u==t) 47 { 48 s+=neck; 49 while (u) 50 { 51 u=pre[u]; 52 j=cur[u]; 53 e[j].flow-=neck; 54 e[j^1].flow+=neck; 55 } 56 neck=inf; 57 } 58 ch=0; 59 break; 60 } 61 } 62 if (ch) 63 { 64 if (--numh[h[u]]==0) return s; 65 int q=-1,tmp=t; 66 for (int i=p[u]; i!=-1; i=e[i].next) 67 { 68 j=e[i].po; 69 if (e[i].flow>0&&h[j]<tmp) 70 { 71 tmp=h[j]; 72 q=i; 73 } 74 } 75 cur[u]=q; h[u]=tmp+1; 76 numh[h[u]]++; 77 if (u) 78 { 79 u=pre[u]; 80 neck=d[u]; 81 } 82 } 83 } 84 return s; 85 } 86 87 bool check(int lim) 88 { 89 len=-1; memset(p,255,sizeof(p)); 90 build(1,t,k); 91 for (int i=1; i<=k; i++) build(0,a[i],1); 92 for (int i=1; i<=n; i++) 93 for (int j=0; j<g[i].size(); j++) 94 build(i,g[i][j],lim); 95 96 if (sap()==k) return 1; return 0; 97 } 98 99 int main() 100 { 101 int cas; 102 scanf("%d",&cas); 103 while (cas--) 104 { 105 scanf("%d%d%d",&n,&m,&k); 106 for (int i=1; i<=k; i++) scanf("%d",&a[i]); 107 for (int i=1; i<=m; i++) 108 { 109 int x,y; 110 scanf("%d%d",&x,&y); 111 g[x].push_back(y); 112 g[y].push_back(x); 113 } 114 t=n+1; 115 int l=1,r=k,ans=k; 116 while (l<=r) 117 { 118 int mid=(l+r)>>1; 119 if (check(mid)) 120 { 121 ans=mid; 122 r=mid-1; 123 } 124 else l=mid+1; 125 } 126 printf("%d ",ans); 127 for (int i=1; i<=n; i++) g[i].clear(); 128 } 129 }