• bzoj usaco 金组水题题解(1)


    UPD:我真不是想骗访问量TAT。。一开始没注意总长度写着写着网页崩了王仓(其实中午的时候就时常开始卡了= =)。。。。损失了2h(幸好长一点的都单独开了一篇)。。。。吓得赶紧分成两坨。。。。TAT。。。。。。。。。。。。。。

    ——————————————————————————————————————————————————————————————————————————————

      写(被虐)了整整一个月b站上usaco的金组题。。。然而到现在总共只写了100道上下TAT(当然是按AC人数降序排列的了)(另外,是用云神的号写的= =毕竟三百大洋)

      大概不到13是自己写的,一半是有大概方向后跑去看题解,剩下的就是毫无思路就去看题解作死的了= =

      感觉金组题还是比较适合自己当前水平的QAQ。。。所以大致的写下题解加深下印象吧。。。对于比较经典而自己又不熟的题打算专门另写题解(瞬间就挖了一个大坑)

    这里贴出50道。。。

    bzoj 1597:[Usaco2008 Mar]土地购买    

      斜率优化入门题。f[i]表示买前i块土地的最小费用

      f[i]=min{
          f[j]+max_w(j+1,i)*max_l(j+1,i),( 0<=j<i )
      }// max_w(j+1,i)和max_l(j+1,i)分别表示第j+1块土地到第i块土地中宽度和长度的最大值

      首先去掉那些被别的土地完全覆盖的土地(因为不会对答案有任何影响),剩下的按宽度排序。宽度升序排序的话,长度一定是降序的(被完全覆盖的都被去掉了)

      方程就变成  f[i]=min{  f[j]+wid[i]*len[j+1]  },(0<=j<i)

      剩下的就是斜率优化了。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define d double
     6 #define ll long long
     7 using namespace std;
     8 const int maxn=50023;
     9 struct zs{
    10     int x,y;
    11 }a[maxn];
    12 bool cant[maxn];
    13 ll f[maxn];
    14 int l,r,dl[maxn];
    15 int i,j,k,n,m;
    16 char rx;int ra;
    17  
    18  
    19 bool cmp(zs a,zs b){return a.x<b.x||(a.x==b.x&&a.y>b.y);
    20 }
    21 bool smaller(int aa,int b,int c){
    22     return  (ll)(f[c]-f[b])*(ll)(a[aa+1].y-a[b+1].y) <= (ll)(f[b]-f[aa])*(ll)(a[b+1].y-a[c+1].y);
    23     /*return (d)(f[i]-f[dlr])/(d)(a[dlr+1].y-a[i+1].y)
    24             <
    25            (d)(f[dlr]-f[pre])/(d)(a[pre+1].y-a[dlr+1].y);*/
    26 }
    27 inline int read(){
    28     rx=getchar();ra=0;
    29     while(rx<'0'||rx>'9')rx=getchar();
    30     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    31 }
    32 int main(){
    33     n=read();
    34     for(i=1;i<=n;i++)a[i].x=read(),a[i].y=read();
    35     sort(a+1,a+1+n,cmp);int tmp=a[n].y;
    36     for(i=n-1;i;i--)
    37         if(a[i].y<=tmp)cant[i]=1;else tmp=a[i].y;  tmp=0;
    38     for(i=1;i<=n;i++)if(!cant[i])a[++tmp].x=a[i].x,a[tmp].y=a[i].y;  n=tmp;
    39     for(i=1;i<=n;i++){
    40         while(l<r&&  (ll)(f[dl[l+1]]-f[dl[l]]) < (ll)a[i].x*(ll)(a[dl[l]+1].y-a[dl[l+1]+1].y)  )l++;
    41         f[i]=f[dl[l]]+(ll)a[i].x*a[dl[l]+1].y;
    42         while(l<r&& smaller(dl[r-1],dl[r],i))r--;dl[++r]=i;
    43     }
    44     printf("%lld
    ",f[n]);
    45     return 0;
    46 }
    View Code

    bzoj 1699:[Usaco2007 Jan]Balanced Lineup排队

      rmq裸题。。。因为不涉及区间修改的操作所以可以用线段树的点树写法(建成一个堆)来写。。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 const int maxn=52333;
     6 int mx[maxn<<2],mn[maxn<<2],a[maxn];
     7 int i,j,k,n,m,len,L,R,ansmax,ansmin;
     8 char s[11];
     9 inline void outx(int x){//len=0;
    10     while(x||!len)s[len++]=x%10,x/=10;
    11     while(len)len--,putchar(s[len]+'0');putchar('
    ');
    12 }
    13 inline void inx(int &x){
    14     int ch;x=0;
    15     for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
    16     for(;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());;
    17 }
    18 int main(){
    19     scanf("%d%d",&n,&m);int dep=0;
    20     while(1<<dep<n)dep++;int stnum=(1<<dep)-1;dep++;
    21     for(i=1;i<=n;i++)inx(a[i]),mx[stnum+i]=mn[stnum+i]=a[i];
    22     for(i=stnum;i;i--){
    23         if(mx[i<<1]>mx[(i<<1)|1])mx[i]=mx[i<<1];else mx[i]=mx[(i<<1)|1];
    24         if(mn[i<<1]<mn[(i<<1)|1])mn[i]=mn[i<<1];else mn[i]=mn[(i<<1)|1];
    25     }
    26     for(i=1;i<=m;i++){
    27         inx(L);inx(R);ansmax=max(a[L],a[R]);ansmin=min(a[L],a[R]);
    28         L+=stnum;R+=stnum;if(L==R)outx(0);else{
    29         for(;(L^R)!=1;L>>=1,R>>=1){
    30             if(R&1){if(mx[R^1]>ansmax)ansmax=mx[R^1];if(mn[R^1]<ansmin)ansmin=mn[R^1];}
    31             if(!(L&1)){if(mx[L^1]>ansmax)ansmax=mx[L^1];if(mn[L^1]<ansmin)ansmin=mn[L^1];}
    32         };outx(ansmax-ansmin);}
    33          
    34     }
    35     return 0;
    36 }
    View Code

    bzoj 1230:[Usaco2008 Nov]lites 开关灯

      线段树区间修改。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=132333;
     6 int num[2][maxn<<1],a[maxn<<1],b[maxn<<1],l[maxn<<1],r[maxn<<1],mid[maxn<<1];
     7 bool rev[maxn<<1];
     8 int i,j,k,n,m,L,R,id,tot;
     9  
    10 char rx;int ra;
    11 inline int read(){
    12     rx=getchar();ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 inline void pushdown(int now,int l,int r){
    17     rev[l]^=1;rev[r]^=1;
    18     swap(num[0][l],num[1][l]);swap(num[0][r],num[1][r]);
    19     rev[now]=0;
    20 }
    21 void change(int now,int a,int b){
    22     if(L<=a&&R>=b){rev[now]^=1;swap(num[0][now],num[1][now]);return;}
    23     if(rev[now])pushdown(now,l[now],r[now]);
    24     if(L<=mid[now])change(l[now],a,mid[now]);
    25     if(R>mid[now])change(r[now],mid[now]+1,b);
    26     num[0][now]=num[0][l[now]]+num[0][r[now]];
    27     num[1][now]=num[1][l[now]]+num[1][r[now]];
    28 }
    29 int query(int now,int a,int b){
    30     if(L<=a&&R>=b)
    31         return num[1][now];
    32     if(rev[now])pushdown(now,l[now],r[now]);
    33     if(R<=mid[now])return query(l[now],a,mid[now]);
    34     else if(L>mid[now])return query(r[now],mid[now]+1,b);
    35     else return query(l[now],a,mid[now])+query(r[now],mid[now]+1,b);
    36 }
    37 void build(int a,int b){
    38     int now=++tot;
    39     num[0][now]=b-a+1;mid[now]=(a+b)>>1;
    40     if(a<b){
    41         l[now]=tot+1;
    42         build(a,mid[now]);r[now]=tot+1;
    43         build(mid[now]+1,b);
    44     }
    45 }
    46 int main(){
    47     n=read();m=read();
    48     build(1,n);
    49     for(i=1;i<=m;i++){
    50         id=read();L=read();R=read();
    51         if(id)printf("%d
    ",query(1,1,n));else change(1,1,n);
    52     }
    53     return 0;
    54 }
    View Code

    bzoj 1666:[Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏

      代码长度知一切系列。。直接模拟即可

    1 #include<cstdio>
    2 int n,ans;
    3 int main(){
    4     for(scanf("%d",&n);n>1;ans++)if(n&1)n=n*3+1;else n>>=1;printf("%d
    ",ans);
    5 }
    View Code

    bzoj 1724:[Usaco2006 Nov]Fence Repair 切割木板

      反过来看就是合并果子。。维护小根堆,每次把最短的两段木板并起来,直到变成一段

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<queue>
     5 #define ll long long
     6 using namespace std;
     7 priority_queue <ll>q;
     8 int i,j,k,n,m;
     9 ll ans,tmp;
    10  
    11 char rx;int ra;
    12 inline int read(){
    13     rx=getchar();ra=0;
    14     while(rx<'0'||rx>'9')rx=getchar();
    15     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    16 }
    17 int main(){
    18     n=read();
    19     for(i=1;i<=n;i++)m=read(),q.push(-m);
    20     for(i=1;i<n;i++){
    21         tmp=q.top();q.pop();tmp+=q.top();q.pop();
    22         ans-=tmp;q.push(tmp);
    23     }
    24     printf("%lld
    ",ans);
    25     return 0;
    26 }
    View Code

    bzoj 1726:[Usaco2006 Nov]Roadblocks第二短路

      求严格次短路。。。最短路改一下。。同时记录到达某个点的最短距离和严格次短距离

      为了压常数把本来的代码长度改长了不少(反正本来也就毫无可读性= =)。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=5001;
     6 const int maxm=100002;
     7 int dis[2][maxn],last[maxn];
     8 struct zs{
     9     int too,dis;
    10     int pre;
    11 }e[maxm<<1];
    12 short dl[23333];
    13 bool u[maxn];
    14 int i,j,k,n,m,a,b,c,tot;
    15  
    16 inline void insert(short a,short b,short c){
    17     e[++tot].too=b;e[tot].dis=c;e[tot].pre=last[a];last[a]=tot;
    18     e[++tot].too=a;e[tot].dis=c;e[tot].pre=last[b];last[b]=tot;
    19 }
    20 char rx;int ra;
    21 inline int read(){
    22     rx=getchar();ra=0;
    23     while(rx<'0'||rx>'9')rx=getchar();
    24     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    25 }
    26 void spfa(){
    27     int l=0,r=1,now,i,a,b;
    28     for(i=0;i<2;i++)memset(dis[i],50,(n+1)*4);
    29     dl[1]=1;u[1]=1;dis[0][1]=0;short j;
    30     while(l<r){
    31         now=dl[++l];u[now]=0;
    32         if(dis[0][now]<dis[1][n])
    33         for(i=last[now],j=e[i].too,a=dis[0][now]+e[i].dis,b=dis[1][now]+e[i].dis;i;i=e[i].pre,j=e[i].too,a=dis[0][now]+e[i].dis,b=dis[1][now]+e[i].dis)
    34             if(dis[0][j]>a){
    35                 if(dis[0][j]<b)dis[1][j]=dis[0][j];else dis[1][j]=b;
    36                 dis[0][j]=a;
    37                 if(!u[j])u[j]=1,dl[++r]=j;
    38             }else if(dis[0][j]<a) 
    39                     if(a<dis[1][j]){
    40                         dis[1][j]=a;
    41                         if(!u[j])u[j]=1,dl[++r]=j;
    42                     }else;
    43              else if(dis[0][j]==a&&b<dis[1][j]){
    44                 dis[1][j]=b;
    45                 if(!u[j])u[j]=1,dl[++r]=j;
    46             }
    47     }
    48 }
    49 int main(){
    50     n=read();m=read();
    51     for(i=1;i<=m;i++)a=read(),b=read(),c=read(),insert(a,b,c);
    52     spfa();
    53     printf("%d
    ",dis[1][n]);
    54     return 0;
    55 }
    View Code

    bzoj 1231:[Usaco2008 Nov]mixup2 混乱的奶牛

      题目是要求能使排列混乱的方案数。语死早。。数据范围显然状压。。

      f[i][j]表示当前已选入列奶牛的状态为i,最后一头牛编号为j的混乱方案数,(0<i<2^n,1<=j<=n)

      f[0][0]=1;f[i][j]=sum{f[i-2^j][k]},(S[k]-S[j]的绝对值>K,j存在于状态i中)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=16;
     7 ll f[16][(1<<maxn)+3],ans;
     8 int pos[(1<<maxn)+3];
     9 int two[17];
    10 short a[17];
    11 int x,y,x1,yy,j,K;
    12 int mx;
    13 int i,k,n;
    14 bool can[17][17];
    15 int main(){
    16     scanf("%d%d",&n,&K);for(i=1;i<=n;i++)scanf("%d",&a[i]);
    17     f[0][0]=1;mx=1<<n;
    18     for(i=1;i<n;i++)for(j=i+1;j<=n;j++)if(max(a[i]-a[j],a[j]-a[i])>K)can[i-1][j-1]=can[j-1][i-1]=1;
    19     for(i=1;i<=n;i++)two[i]=1<<(i-1),pos[two[i]]=i-1,f[i-1][two[i]]=1;
    20     for(j=1;j<=mx&&j>0;j++)
    21         for(x=j,y=x&(-x),i=pos[y];x;x-=y,y=x&(-x),i=pos[y])
    22             for(x1=j,yy=x1&(-x1),k=pos[yy];x1;x1-=yy,yy=x1&(-x1),k=pos[yy])if(i!=k&&can[i][k])
    23             f[k][j]+=f[i][j^yy];
    24     for(i=0;i<n;i++)ans+=f[i][mx-1];
    25     printf("%lld
    ",ans);
    26     return 0;
    27 }
    View Code

     

    bzoj 1572: [Usaco2009 Open]工作安排Job

      按截止时间降序排序。也就是时间从大到小枚举,每个时间点安排价值最大、且截止时间在当前时间点之前的工作

      具体实现就不能一个一个时间点枚举了。。在相邻工作的截止时间之间的时间点,可以完成的工作都是不变的

      单调队列优化一下。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<queue>
     6 #define ll long long
     7 using namespace std;
     8 const int maxn=100003;
     9 struct zs{
    10     int tim,val;
    11 }a[maxn];
    12 priority_queue<int>q;
    13 int i,j,k,n,m,top;
    14 ll ans;
    15 int ra,size;char rx;
    16  
    17 inline int read(){
    18     rx=getchar();ra=0;
    19     while(rx<'0'||rx>'9')rx=getchar();
    20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    21 }
    22 bool cmp(zs a,zs b){
    23     return a.tim<b.tim;
    24 }
    25 int main(){
    26     n=read();
    27     for(i=1;i<=n;i++)a[i].tim=read(),a[i].val=read();
    28     sort(a+1,a+1+n,cmp);
    29      
    30     for(i=n;i;i--){
    31         q.push(a[i].val);size++;
    32         if(a[i].tim-a[i-1].tim>size)j=size;else j=a[i].tim-a[i-1].tim;
    33         while(j--)ans+=q.top(),q.pop(),size--;
    34     }
    35     printf("%lld
    ",ans);
    36     return 0;
    37 }
    View Code

    bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级

      分层图最短路。。。dis[i][j]表示到i点,共更新了j条边的最短路径长度。

      按照更新的边数建K+1层图,第i层表示当前更新了(i-1)条边。除了在本层内扩展外,第1~K层的点还可以向更高的一层扩展(更新当前边为0)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 #define ll long long
     6 using namespace std;
     7 const int maxn=10001;
     8 const int maxm=50001;
     9 const int mx=233333;
    10 struct poi{
    11     short pos;int dis;short int x;
    12 }tmp;
    13 priority_queue<poi>q;
    14 struct zs{
    15     short too;
    16     int dis,pre;
    17 }e[maxm<<1];
    18 int last[maxn],dis[21][maxn];
    19 ll dist[21][maxn],ans;
    20 int i,j,k,n,m,K,tot,a,b;
    21 bool u[21][maxn];
    22  
    23 int ra;char rx;
    24 inline int read(){
    25     rx=getchar();ra=0;
    26     while(rx<'0'||rx>'9')rx=getchar();
    27     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    28 }
    29 bool operator <(poi a,poi b){return a.dis>b.dis;} 
    30 void spfa(){
    31     int l=0,r=1,i;short now;short int nowx;
    32     for(i=0;i<=K;i++)memset(dist[i],50,(n+1)<<3);
    33     ans=dist[0][n];
    34     u[0][1]=1;dist[0][1]=0;
    35     tmp.dis=0;tmp.pos=1;tmp.x=0;q.push(tmp) ;
    36     while(!q.empty()){
    37         tmp=q.top();q.pop();
    38         now=tmp.pos;nowx=tmp.x;u[nowx][now]=0;
    39         if(dist[nowx][now]<ans)
    40         for(i=last[now];i;i=e[i].pre){
    41             if(dist[nowx][e[i].too]>dist[nowx][now]+e[i].dis){
    42                 dist[nowx][e[i].too]=dist[nowx][now]+e[i].dis;
    43                 if(e[i].too==n)ans=min(ans,dist[nowx][e[i].too]);
    44                 if(!u[nowx][e[i].too]){
    45                     u[nowx][e[i].too]=1;
    46                     tmp.pos=e[i].too;tmp.x=nowx;tmp.dis=dist[nowx][e[i].too];
    47                     q.push(tmp);
    48                 }
    49             }
    50             if(nowx<K&&dist[nowx+1][e[i].too]>dist[nowx][now]){
    51                 dist[nowx+1][e[i].too]=dist[nowx][now];
    52                 if(e[i].too==n)ans=min(ans,dist[nowx+1][e[i].too]);
    53                 if(!u[nowx+1][e[i].too]){
    54                     u[nowx+1][e[i].too]=1;
    55                     tmp.pos=e[i].too;tmp.x=nowx+1;tmp.dis=dist[nowx+1][e[i].too];
    56                     q.push(tmp);
    57                 }
    58             }
    59         }
    60     }
    61 }
    62 int main(){
    63     n=read();m=read();K=read();
    64     for(i=1;i<=m;i++){
    65         a=read();b=read();
    66         e[++tot].dis=e[tot+1].dis=read();
    67         e[tot].too=b;e[tot].pre=last[a];last[a]=tot++;
    68         e[tot].too=a;e[tot].pre=last[b];last[b]=tot;
    69     }
    70     spfa();
    71     printf("%lld
    ",ans);
    72     return 0;
    73 }
    View Code

    bzoj 1708: [Usaco2007 Oct]Money奶牛的硬币

      完全背包。。。一开始竟然没看出来王仓

    bzoj 1690: [Usaco2007 Dec]奶牛的旅行

      01分数规划。。。二分答案为mid,将原图的边(u,v,time)重建为(u,v,fun[v]-time*mid),如果新图中有负环那么当前答案可行

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define d double
     5 using namespace std;
     6 const int maxn=1021;
     7 const int maxm=5023;
     8 const d eps=1e-5;
     9 struct zs{
    10     int too,pre,t;
    11     d dis;
    12 }e[maxm];
    13 int i,j,k,n,m,tot,a,b,c;
    14 d dist[maxn],l,r,mid;
    15 int val[maxn],last[maxn];
    16 bool u[maxn],uu[maxn],flag;
    17  
    18 inline int read(){
    19     char x;int ans=0;
    20     for(x=getchar();x<'0'||x>'9';x=getchar());
    21     for(;x>='0'&&x<='9';x=getchar())ans*=10,ans+=x-48;
    22     return ans;
    23 }
    24 inline void insert(int a,int b,int c){
    25     e[++tot].too=b;e[tot].pre=last[a];e[tot].t=c;last[a]=tot;
    26 }
    27 bool spfa(int x){
    28     u[x]=1;uu[x]=1;
    29     for(int i=last[x];i;i=e[i].pre)if(dist[e[i].too]>dist[x]+e[i].dis){
    30         dist[e[i].too]=dist[x]+e[i].dis;
    31         if(u[e[i].too]){flag=1;return 1;}
    32         if(spfa(e[i].too))return 1;
    33     }
    34     u[x]=0;
    35     return 0;
    36 }
    37 bool check(d mid){
    38     memset(uu,0,n+1);
    39     memset(u,0,n+1);
    40     memset(dist,0,4*(n+1));
    41     flag=0;
    42     for(int i=1;i<=n;i++)if(!uu[i])if(spfa(i))return 1;
    43     return 0;
    44 }
    45 int main(){
    46     n=read();m=read();
    47     for(i=1;i<=n;i++)val[i]=read();
    48     for(i=1;i<=m;i++)a=read(),b=read(),c=read(),insert(a,b,c),r=max(r,(d)val[b]/(d)c);
    49     l=0.0;
    50     while(l+eps<=r){
    51         mid=(l+r)/2.0;
    52         for(i=1;i<=m;i++)e[i].dis=(d)(-val[e[i].too])+mid*e[i].t;
    53         if(check(mid))l=mid;else r=mid-eps;
    54     }
    55     printf("%.2lf
    ",l);
    56     return 0;
    57 }
    View Code

    bzoj 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

      字符串http://www.cnblogs.com/czllgzmzl/p/4989723.html

    bzoj 1692: [Usaco2007 Dec]队列变换

      贪心。。。当前剩下的队伍为[l,r],每次比较 l到r 这段字符串和 r到l 这段字符串,哪段小选哪段

      比较字符串大小的时候可以用hash+二分求出最长公共前缀的长度,再比较下一位的大小

      hash用unsigned int不会被卡。。。感人。。明显优势#1

      然而O(n^2)暴力可过TAT

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ull unsigned int
     6 using namespace std;
     7 const int maxn=30003;
     8 char s[maxn];
     9 ull pre[maxn],jc[maxn],val1,val2,pre1[maxn];
    10 short i,j,k,n,m,l,r,mid,len,L,R;
    11  
    12 inline short getlen(){
    13     if(s[L]!=s[R])return 0;
    14     l=1;r=R-L+1;
    15     if(pre[L+r-1]-pre[L-1]*jc[r]==pre1[R-r+1]-pre1[R+1]*jc[r])return r;r--;
    16     while(l<r){
    17         mid=(l+r+1)>>1;//return mid;
    18         val1=pre[L+mid-1]-pre[L-1]*jc[mid];
    19         val2=pre1[R-mid+1]-pre1[R+1]*jc[mid];
    20         if(val1!=val2)r=mid-1;else l=mid;
    21         if(s[L+l]!=s[R-l])return l;
    22     }
    23     return l;
    24 }
    25 inline bool bigger(){
    26     if(s[L]!=s[R])return s[L]>s[R];
    27     len=getlen();
    28     if(len==R-L+1)return 1;
    29     else return s[L+len]>s[R-len];
    30 }
    31 int main(){
    32     scanf("%d",&n);
    33     for(i=1;i<=n;i++)for(s[i]=getchar();s[i]<'A'||s[i]>'Z';s[i]=getchar());
    34     jc[0]=1;for(i=1;i<=n;i++)jc[i]=jc[i-1]*107;
    35     for(i=1;i<=n;i++)pre[i]=pre[i-1]*107+(ull)s[i]-'A';
    36     for(i=n;i;i--)pre1[i]=pre1[i+1]*107+(ull)s[i]-'A';
    37     L=1;R=n;
    38     for(i=1;i<=n;i++)if(bigger()){
    39         putchar(s[R--]);
    40         if(i%80==0)putchar('
    ');
    41     }else {putchar(s[L++]);if(i%80==0)putchar('
    ');}
    42     return 0;
    43 }
    View Code

    bzoj 1782: [Usaco2010 Feb]slowdown 慢慢游

      dfs序,一头牛走到点i,相当于将点i所在子树的权值都+1,查询的时候查询牛要走到的点的权值

      也可以差分,变成点修改+区间查询,用树状数组就行了。。。

      太傻逼用线段树然后被常数感动哭了

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=140233;
     6 struct zs{
     7     int too,pre;
     8 }e[200122];
     9 int pos[100122],last[100233],size[100233];
    10 int l[maxn<<1],r[maxn<<1],add[maxn<<1],A[maxn<<1],B[maxn<<1],mid[maxn<<1];
    11 int i,j,k,n,m,a,b,c,tim,tot,tott;
    12 int ra;char rx;
    13  
    14  
    15 inline int read(){
    16     rx=getchar();ra=0;
    17     while(rx<'0'||rx>'9')rx=getchar();
    18     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    19 }
    20 inline void insert(int a,int b){
    21     e[++tot].too=b;e[tot].pre=last[a];last[a]=tot;
    22     e[++tot].too=a;e[tot].pre=last[b];last[b]=tot;
    23 }
    24 void dfs(int x,int pre){
    25     size[x]=1;pos[x]=++tim;
    26     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=pre){
    27         dfs(e[i].too,x);size[x]+=size[e[i].too];
    28     }
    29 }
    30 void build(int a,int b){
    31     int now=++tott;
    32     A[now]=a;B[now]=b;mid[now]=(a+b)>>1;
    33     if(a<b){
    34         l[now]=tott+1;build(a,mid[now]);
    35         r[now]=tott+1;build(mid[now]+1,b);
    36     }
    37 }
    38 inline void pushdown(int now){
    39     add[l[now]]+=add[now];add[r[now]]+=add[now];
    40     add[now]=0;
    41 }
    42 void insert(int now,int c,int d){
    43     if(c<=A[now]&&B[now]<=d){add[now]++;return;}
    44     if(add[now])pushdown(now);
    45     if(c<=mid[now])insert(l[now],c,d);
    46     if(d>mid[now])insert(r[now],c,d);
    47 }
    48 int query(int now,int c){
    49     if(A[now]==B[now])return add[now];
    50     if(add[now])pushdown(now);
    51     if(c<=mid[now])return query(l[now],c);else return query(r[now],c);
    52 }
    53 int main(){
    54     n=read();
    55     for(i=1;i<n;i++)a=read(),b=read(),insert(a,b);
    56     dfs(1,0);
    57     build(1,n);
    58     for(i=1;i<=n;i++){
    59         a=read();printf("%d
    ",query(1,pos[a]));
    60         insert(1,pos[a],pos[a]+size[a]-1);
    61     }
    62 }
    View Code

    bzoj 1827: [Usaco2010 Mar]gather 奶牛大集会

      O(n^2)的暴力就是对每个点都把整棵树遍历一遍

      考虑一下,假设求出了到当前点i的不方便值为fasum,如何快速计算i的儿子的不方便值

      先预处理出每个点的子树内奶牛总数存在size[],那么对于i的某个儿子j,所有不在j的子树里的奶牛都得多走从i->j这段路,而j子树里的奶牛都可以少走i->j这段路

      nowsum=fasum+(cownum-size[j])*dis(i,j)-size[j]*dis(i,j);

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=100023;
     7 struct zs{
     8     int too,pre;
     9     ll dis;
    10 }e[maxn<<1];
    11 int size[maxn],last[maxn],tot,fa[maxn];
    12 int i,j,k,n,m,a,b,poinum;
    13 int ra;char rx;
    14 ll nowsum,ans;
    15  
    16  
    17 inline int read(){
    18     rx=getchar();ra=0;
    19     while(rx<'0'||rx>'9')rx=getchar();
    20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    21 }
    22 void dfs(int x,ll fasum){
    23     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&size[e[i].too]<<1>poinum){
    24         nowsum=fasum+(ll)(poinum-size[e[i].too]*2)*e[i].dis;
    25         if(nowsum<ans)ans=nowsum;
    26         dfs(e[i].too,nowsum);
    27     }
    28 }
    29 void dfs1(int x){
    30     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x])
    31         fa[e[i].too]=x,dfs1(e[i].too),size[x]+=size[e[i].too],nowsum+=(ll)size[e[i].too]*e[i].dis;
    32 }
    33 int main(){
    34     n=read();
    35     for(i=1;i<=n;i++)size[i]=read(),poinum+=size[i];
    36     for(i=1;i<n;i++){
    37         a=read();b=read();e[++tot].dis=e[tot+1].dis=read();
    38         e[tot].too=b;e[tot].pre=last[a];last[a]=tot;
    39         e[++tot].too=a;e[tot].pre=last[b];last[b]=tot;
    40     }
    41     dfs1(1);ans=nowsum;
    42     dfs(1,nowsum);
    43     printf("%lld
    ",ans);
    44     return 0;
    45 }
    View Code

    bzoj 1592: [Usaco2008 Feb]Making the Grade 路面修整

      显然(看题解才知道的TAT)一段路修整后,高度一定和原来那些路中的某一段相等。。。。所以把高度离散化一下就变成O(n^2)的dp了。。。

      不下降的情况:f[i][j]表示前i段路,第i段高度修整为j的最小支出

              f[i][j]=min{ f[i-1][k]+abs(h[i]-h[j]) },(k<=j)转移的过程中顺便记录一下k就行了

      不上升就倒过来做一遍

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define uint unsigned int
     7 #define ll long long
     8 using namespace std;
     9 const int maxn=2005;
    10 ll f[maxn][maxn],mn,ans;
    11 int a[maxn],b[maxn];
    12 int ra;char rx;
    13 int i,j,k,n,m,nn;
    14 inline int read(){
    15     rx=getchar();ra=0;
    16     while(rx<'0'||rx>'9')rx=getchar();
    17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    18 }
    19 inline short getpos(int x){
    20     short l=1,r=nn,mid;
    21     while(l<r){
    22         mid=(l+r+1)>>1;
    23         if(b[mid]<=x)l=mid;else r=mid-1;
    24     }return l;
    25 }
    26 int main(){
    27     n=read();for(i=1;i<=n;i++)a[i]=read();memcpy(b,a,(n+1)<<2);
    28     sort(b+1,b+1+n);
    29     nn=unique(b+1,b+1+n)-b-1;
    30     for(i=1;i<=n;i++)a[i]=getpos(a[i]);
    31     for(i=1;i<=n;i++)memset(f[i],50,(nn+1)<<3);ans=f[1][0];
    32     for(i=1;i<=n;i++){mn=f[i-1][0];
    33         for(j=1;j<a[i];j++){
    34             if(f[i-1][j]<mn)mn=f[i-1][j];
    35             f[i][j]=mn+b[a[i]]-b[j];
    36         }
    37         for(j=a[i];j<=nn;j++)mn=min(mn,f[i-1][j]),f[i][j]=mn+b[j]-b[a[i]];
    38     }
    39     for(i=1;i<=nn;i++)if(f[n][i]<ans)ans=f[n][i];
    40       
    41     for(i=1;i<=n;i++)memset(f[i],50,(nn+1)<<3);
    42     for(i=1;i<=n;i++){mn=f[i-1][nn];
    43         for(j=nn;j>a[i];j--){
    44             if(f[i-1][j]<mn)mn=f[i-1][j];
    45             f[i][j]=mn+b[j]-b[a[i]];
    46         }
    47         for(j=a[i];j;j--)mn=min(mn,f[i-1][j]),f[i][j]=mn+b[a[i]]-b[j];
    48     }
    49     for(i=1;i<=nn;i++)if(f[n][i]<ans)ans=f[n][i];
    50     printf("%lld
    ",ans);
    51     return 0;
    52 }
    View Code

    bzoj 1725:[Usaco2006 Nov]Corn Fields牧场的安排

      数据范围就是状压了。。

      f[i][j]表示前i行,第i行种草状态为j的总方案数。

      f[i][j]=sum{ f[i-1][k] },j状态和k状态是合法的(没种到那一行贫瘠的土地,且没有草相邻),且j&k==0(没有上下两行没有草在同一列)

      预处理了各种非法情况结果比直接枚举慢= =

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const short maxn=13;
     6 const int modd=100000000;
     7 short two[maxn],mapl[maxn],mx;
     8 short map[(1<<12)+2][400];
     9 short i,j,k,n,m,tmp,now,pre;
    10 int f[13][(1<<12)+1],ans;
    11 char x;
    12 int main(){
    13     scanf("%d%d",&n,&m);
    14     mx=1<<m;two[1]=1;
    15     for(i=2;i<=m;i++)two[i]=two[i-1]<<1;
    16     for(i=0;i<mx;i++){
    17         bool flag=0;
    18         for(j=1;j<m&&!flag;j++)if(i&two[j]&&i&two[j+1])flag=1;
    19         if(!flag)map[0][++map[0][0]]=i;
    20     }
    21     for(i=1;i<mx;i++){
    22         tmp=i-(i&(-i));
    23         for(j=map[tmp][0];j;j--)if(!(map[tmp][j]&i))map[i][++map[i][0]]=map[tmp][j];
    24     }
    25     now=1;pre=0;
    26     f[0][0]=1;
    27     for(i=1;i<=n;i++){
    28         now=i;pre=i-1;
    29         for(j=1;j<=m;j++){for(x=getchar();x<'0'||x>'1';x=getchar());mapl[i]+=(x=='0')*two[j];}
    30         for(j=map[0][0],tmp=map[0][j];j;j--,tmp=map[0][j])if(!(tmp&mapl[i-1])&&f[pre][tmp])
    31             for(k=map[tmp][0];k;k--)if(!(map[tmp][k]&mapl[i]))
    32                 f[now][map[tmp][k]]+=f[pre][tmp],f[now][map[tmp][k]]-=(f[now][map[tmp][k]]>=modd)?modd:0;
    33     }
    34     for(i=0;i<mx;i++)ans+=f[n][i],ans-=(ans>=modd)?modd:0;
    35     printf("%d
    ",ans);
    36     return 0;
    37 }
    View Code

    bzoj 1711:[Usaco2007 Open]Dingin吃饭

      二分图最大匹配。。s连奶牛,饮料和食品连t,每头牛往它要吃的东西连边。。。用dinic比匈牙利算法慢了点

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=103;
     6 struct zs{
     7     short too,flow;
     8     int pre;
     9 }e[100233];
    10 short dis[423],dl[423];
    11 short l,r,now;
    12 int last[423],tot,s,t,n,m1,m2,num1,num2,a,i,j,ans;
    13   
    14 int ra;char rx;
    15 inline int read(){
    16     rx=getchar();ra=0;
    17     while(rx<'0'||rx>'9')rx=getchar();
    18     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    19 }
    20 inline void insert(short a,short b){
    21     e[++tot].too=b;e[tot].flow=1;e[tot].pre=last[a];last[a]=tot;
    22     e[++tot].too=a;e[tot].flow=0;e[tot].pre=last[b];last[b]=tot;
    23 }
    24 bool bfs(){
    25     memset(dis,255,(t+1)<<1);
    26     l=0;r=1;dl[1]=s;dis[s]=0;
    27     short now;int i;
    28     while(l<r){
    29         now=dl[++l];
    30         for(i=last[now];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==-1)
    31             dl[++r]=e[i].too,dis[e[i].too]=dis[now]+1;
    32     }
    33     return dis[t]!=-1;
    34 }
    35 short dfs(short x,short mx){
    36     if(!mx||x==t)return mx;
    37     short w,used=0;int i;
    38     for(i=last[x];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==dis[x]+1){
    39         w=dfs(e[i].too,min(mx-used,(int)e[i].flow));if(w){
    40             e[i].flow-=w;e[((i-1)^1)+1].flow+=w;
    41             used+=w;if(used==mx)return used;
    42         }
    43     }
    44     dis[x]=-1;return used;
    45 }
    46 int main(){
    47     n=read();m1=read();m2=read();s=0;t=n*2+m1+m2+1;
    48     for(i=1;i<=n;i++){
    49         insert(i+m1,i+m1+n);
    50         num1=read();num2=read();
    51         for(j=1;j<=num1;j++)a=read(),insert(a,i+m1);
    52         for(j=1;j<=num2;j++)a=read(),insert(i+m1+n,a+m1+n*2);
    53     }
    54     for(i=1;i<=m1;i++)insert(0,i);
    55     for(i=1;i<=m2;i++)insert(n*2+m1+i,t);
    56     while(bfs())ans+=dfs(s,23333);
    57     printf("%d
    ",ans);
    58     return 0;
    59 }
    View Code

    bzoj 1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富

      裸dp。f[i][j]表示走到第i列,第j行最大财富,

      f[1][1]=map[1][j];f[i][j]=max{f[i-1][j-1],f[i-1][j],f[i-1][j+1]}

      注意边界。。。。第0、n+1行和第1列初始化成负无穷QAQ

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxh=102;
     6 int map[maxh][maxh];
     7 int i,j,k,n,m,now,pre;
     8 int f[2][maxh];
     9 char x;
    10 inline void read(int &ans){
    11     x=getchar();int fh=1;
    12     while((x<'0'||x>'9')&&x!='-')x=getchar();
    13     if(x=='-')fh=-1,x=getchar();
    14     while(x>='0'&&x<='9')ans*=10,ans+=x-48,x=getchar();ans*=fh;
    15 }
    16 int main(){
    17     read(n);read(m);
    18     for(i=1;i<=n;i++)for(j=1;j<=m;j++)read(map[i][j]);
    19     f[0][1]=map[1][1];for(i=2;i<=n;i++)f[0][i]=-1023333333;
    20     for(i=2;i<=m;i++){
    21         pre=i&1;now=pre^1;f[pre][0]=f[pre][n+1]=-1023333333;
    22         for(j=1;j<=n;j++)f[now][j]=max(f[pre][j],max(f[pre][j-1],f[pre][j+1]))+map[j][i];
    23     }
    24     printf("%d
    ",f[now][n]);
    25     return 0;
    26 }
    View Code

    bzoj 1571: [Usaco2009 Open]滑雪课Ski

      dp,f[i][j]表示前i时间过后,能力值为j的最大滑雪次数

       f[i][j]=max{

        f[i-1][j],//开颓

        f[ i-Dmin[j] ][ j ]+1,//先把斜坡按所需能力排序,Dmin[j]表示 所需能力值<=j的斜坡中 所需最小时长

        g[ i-L[k] ],//上第k节课(前提是有课= =),g[i]表示f[i][1..100]中的最大值

      }

       代码丑得不忍直视。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 const int maxn=10001;
     8 struct lesson{
     9     short st,l,val;
    10 }a[101];
    11 struct poi{
    12     short need,cost;
    13 }b[maxn];
    14 short f[maxn][101],g[maxn],ans;
    15 short cost[maxn],need[maxn],M[maxn],L[maxn],aa[101];
    16 bool can[101];
    17 int i,j,k,n,m,maxt,nn;
    18 int ra;char rx;
    19 inline int read(){
    20     rx=getchar();ra=0;
    21     while(rx<'0'||rx>'9')rx=getchar();
    22     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    23 }
    24 bool cmp(lesson a,lesson b){
    25     return a.st<b.st;
    26 }
    27 bool cmp1(poi a,poi b){
    28     return a.need<b.need;
    29 }
    30 bool cmp2(poi a,poi b){
    31     return a.cost<b.cost;
    32 }
    33 inline short getpos(int x){
    34     short l=1,r=nn,mid;
    35     while(l<r){
    36         mid=(l+r+1)>>1;
    37         if(aa[mid]<=x)l=mid;else r=mid-1;
    38     }
    39     return l;
    40 }
    41 int main(){
    42     maxt=read();n=read();m=read();
    43     for(i=1;i<=n;i++)a[i].st=read(),a[i].l=read(),a[i].val=aa[i]=read();
    44     sort(a+1,a+1+n,cmp);aa[n+1]=1;sort(aa,aa+2+n);nn=unique(aa+1,aa+2+n)-aa-1;//printf("   %d
    ",nn);
    45     for(i=1;i<=n;i++)a[i].val=getpos(a[i].val);
    46     for(i=1;i<=m;i++)b[i].need=read(),b[i].cost=read();
    47     sort(b+1,b+1+m,cmp1);int tmp=1,tmp1=b[1].cost;
    48     for(i=2;i<=m;i++)if(b[i].cost<tmp1)tmp1=b[i].cost,b[++tmp].cost=b[i].cost,b[tmp].need=b[i].need;
    49     m=tmp;
    50     sort(b+1,b+1+m,cmp2);
    51     int nowlesson=0,nowpoi=0;
    52     memset(f[0],150,sizeof(f[0]));f[0][1]=0;can[1]=1;
    53     for(i=1;i<=maxt;i++){
    54         memcpy(f[i],f[i-1],(nn+1)<<1);
    55         while(nowpoi<m&&b[nowpoi+1].cost<=i)nowpoi++;
    56         while(nowlesson<n&&a[nowlesson+1].st+a[nowlesson+1].l==i)nowlesson++,f[i][a[nowlesson].val]=g[a[nowlesson].st],can[a[nowlesson].val]=1;
    57         for(j=1;j<=nn;j++)if(can[j]){
    58             for(k=1;k<=nowpoi;k++)if(aa[j]>=b[k].need&&f[i-b[k].cost][j]>=f[i][j])f[i][j]=f[i-b[k].cost][j]+1;
    59     //      printf("%d %d    %d
    ",i,j,f[i][j]);
    60             if(f[i][j]>g[i])g[i]=f[i][j];
    61         }//printf("   gi:%d
    ",g[i]);
    62     }
    63     for(i=1;i<=nn;i++)ans=max(ans,f[maxt][i]);
    64     printf("%d
    ",ans);
    65     return 0;
    66 }
    View Code

    bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞

      询问图中有没有负环。。。(回到过去必须是回到起点并且时间比出发时还早)

      dfs版的spfa判负环。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=502;
     6 const int maxm=5233;
     7 struct zs{
     8     short too,pre,dis;
     9 }e[maxm];
    10 short i,j,k,n,m,tot,T,w,a,b;
    11 short last[maxn];
    12 int dis[maxn];
    13 bool u[maxn],uu[maxn];
    14 short ra;char rx;
    15 inline short read(){
    16     rx=getchar();ra=0;
    17     while(rx<'0'||rx>'9')rx=getchar();
    18     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    19 }
    20 bool dfs(short x){
    21     short i,j;
    22     uu[x]=u[x]=1;
    23     for(i=last[x];i;i=e[i].pre)if(dis[e[i].too]>dis[x]+e[i].dis){
    24         dis[e[i].too]=e[i].dis+dis[x];
    25         if(u[e[i].too]||dfs(e[i].too)){u[x]=0;return 1;}
    26     }u[x]=0;
    27     return 0;
    28 }
    29 bool spfa(){
    30     short j;
    31     for(j=1;j<=n;j++)if(!uu[j]&&dfs(j))return 1;
    32     return 0;
    33 }
    34 int main(){
    35     T=read();
    36     for(int ii=1;ii<=T;ii++){
    37         n=read();m=read();w=read();
    38         if(ii>1)memset(last,0,(n+1)<<1),memset(uu,0,n+1),tot=0;
    39         for(i=1;i<=m;i++){
    40             e[++tot+1].too=a=read();e[tot].too=b=read();e[tot].dis=e[tot+1].dis=read();
    41             e[tot].pre=last[a];last[a]=tot++;
    42             e[tot].pre=last[b];last[b]=tot;
    43         }
    44         for(i=1;i<=w;i++)a=read(),e[++tot].too=read(),e[tot].dis=-read(),e[tot].pre=last[a],last[a]=tot;
    45         bool flag=spfa();
    46         if(flag)printf("YES
    ");else printf("NO
    ");
    47     }
    48     return 0;
    49 }
    View Code

    bzoj 1596: [Usaco2008 Jan]电话网络

      树形dp。。http://www.cnblogs.com/czllgzmzl/p/5064626.html

    bzoj 2442: [Usaco2011 Open]修剪草坪

      单调队列。。

      最大效率==总效率-最小损失效率。f[i]表示前i头奶牛,因为不能有连续K只奶牛而损失的效率的最小值(第i头牛不安排)。

      f[i]=min{ f[j] } +E[i],(i-j<=K)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=100023;
     7 int dl[maxn];
     8 ll f[maxn],sum;
     9 int i,j,k,n,m,l,r;
    10 int ra;char rx;
    11 inline int read(){
    12     rx=getchar();ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 int main(){
    17     n=read();k=read()+1;
    18     l=r=1;dl[1]=0;
    19     for(i=1;i<=n+1;i++){
    20         while(l<r&&i-dl[l]>k)l++;
    21         if(i<=n)j=read();else j=0;
    22         f[i]=f[dl[l]]+j;sum+=j;
    23         while(l<=r&&f[dl[r]]>=f[i])r--;
    24         dl[++r]=i;
    25     }
    26     printf("%lld
    ",sum-f[dl[l]]);
    27     return 0;
    28 }
    View Code

    bzoj 1233:  [Usaco2009Open]干草堆tower

      斜率优化。。。

      看了别人(似乎是wshjzaa?)题解才明白TAT  http://www.cnblogs.com/sagitta/p/4650681.html

      注:题解最后似乎有个地方<和>打反了?(或者是我语文不好。。)

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 const int maxn=100003;
     6 int f[maxn],pre[maxn],g[maxn];
     7 int i,j,k,n,m,l,r;
     8 int dl[maxn];
     9  
    10 short ra;char rx;
    11 inline short read(){
    12     rx=getchar();ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 int main(){
    17     scanf("%d",&n);
    18     for(i=1;i<=n;i++)pre[i]=read()+pre[i-1];
    19     l=r=1;dl[r]=n+1;
    20     for(i=n;i;i--){
    21         while(l<=r&&f[dl[l]]<=pre[dl[l]-1]-pre[i-1])l++;l--;
    22         f[i]=pre[dl[l]-1]-pre[i-1];
    23         g[i]=g[dl[l]]+1;
    24         while(l<=r&&pre[dl[r]-1]-f[dl[r]]<=pre[i-1]-f[i])r--;
    25         dl[++r]=i;
    26     }
    27     printf("%d
    ",g[1]);
    28     return 0;
    29 }
    View Code

    bzoj 1707:  [Usaco2007 Nov]tanning分配防晒霜

      贪心。。http://www.cnblogs.com/czllgzmzl/p/5064620.html

    bzoj 1709: [Usaco2007 Oct]Super Paintball超级弹珠

      难得的傻逼题。。可以O(n^3)无脑暴力。。。

      或者是先预处理一下,读入时处理出 每一行、每一列、每一条对角线的对手数量。。。当然还有每一个点上的对手数

      某个射击位置(x,y)能打到的对手数就是 第x行的对手数+第y行的对手数+所在两条对角线的对手数-3*((x,y)这个点上的对手数)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=105;
     7 int h[maxn],l[maxn],dj1[maxn<<1],dj2[maxn<<1],map[maxn][maxn];
     8 int i,j,k,n,m,ans,a,b;
     9 int ra;char rx;
    10 inline int read(){
    11     rx=getchar();ra=0;
    12     while(rx<'0'||rx>'9')rx=getchar();
    13     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    14 }
    15 int main(){
    16     n=read();m=read();
    17     for(i=1;i<=m;i++)a=read(),b=read(),h[a]++,l[b]++,dj1[a+b-1]++,dj2[a-b+n]++,map[a][b]++;
    18     for(i=1;i<=n;i++)for(j=1;j<=n;j++)
    19     if(h[i]+l[j]+dj1[i+j-1]+dj2[i-j+n]-map[i][j]*3==m)ans++;
    20     printf("%d
    ",ans);
    21     return 0;
    22 }
    View Code

    bzoj 1576: [Usaco2009 Jan]安全路经Travel

      并查集正确姿势。。http://www.cnblogs.com/czllgzmzl/p/5064758.html

    bzoj 1593: [Usaco2008 Feb]Hotel 旅馆

      比较正常的线段树题目。。。维护一段只有0和1的区间里面,最长的0的长度,从左边开始、从右边开始的最长的0的长度

      每次查找区间位置的时候,如果左子树里的够长就去左子树找,不然试试跨过左右子树的那段,最后才去右子树里找。(无解直接输出0)

      区间修改的话就维护一个标记,表示当前区间被覆盖的情况(客人订满、客人退空、已下传)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 const int maxn=66233;
     6 const int inf=1023333333;
     7 int mx[maxn<<1],l[maxn<<1],r[maxn<<1],lmx[maxn<<1],rmx[maxn<<1],size[maxn<<1],mid[maxn<<1],mxpos[maxn<<1];
     8 short cov[maxn<<1];//0:全可用,1:全不可,2:其他或已下传 
     9 int ra;char rx;
    10 int i,j,k,n,m,ans,tot,L,R,id,pos;
    11 inline void pushup(int now,int l,int r){
    12     lmx[now]=lmx[l];if(lmx[l]==size[l])lmx[now]+=lmx[r];
    13     rmx[now]=rmx[r];if(rmx[r]==size[r])rmx[now]+=rmx[l];
    14     mx[now]=rmx[l]+lmx[r];mxpos[now]=mid[now]-rmx[l]+1;if(mx[l]>mx[now])mx[now]=mx[l],mxpos[now]=mxpos[l];if(mx[r]>mx[now])mx[now]=mx[r],mxpos[now]=mxpos[r];
    15 }
    16 void build(int a,int b){
    17     int now=++tot;mid[now]=(a+b)>>1;
    18     mx[now]=lmx[now]=rmx[now]=size[now]=b-a+1;mxpos[now]=a;cov[now]=2;
    19     if(a<b){
    20         l[now]=tot+1;build(a,mid[now]);
    21         r[now]=tot+1;build(mid[now]+1,b);
    22     }
    23 }
    24 inline void pushdown(int now,int l,int r){
    25     if(cov[now]){
    26         lmx[l]=lmx[r]=rmx[l]=rmx[r]=mx[l]=mx[r]=mxpos[r]=mxpos[l]=0;
    27         cov[l]=cov[r]=1;
    28     }else{
    29         lmx[l]=rmx[l]=mx[l]=size[l];mxpos[l]=mid[now]-size[l]+1;
    30         lmx[r]=rmx[r]=mx[r]=size[r];mxpos[r]=mid[now]+1;
    31         cov[l]=cov[r]=0;
    32     }
    33     cov[now]=2;
    34 }
    35 void update(int now,int a,int b,int c,int d,int col){
    36     if(c<=a&&d>=b){
    37         cov[now]=col;
    38         if(col)lmx[now]=rmx[now]=mx[now]=mxpos[now]=0;
    39         else lmx[now]=rmx[now]=mx[now]=size[now],mxpos[now]=a;
    40         return;
    41     }
    42     if(cov[now]!=2)pushdown(now,l[now],r[now]);
    43     if(c<=mid[now])update(l[now],a,mid[now],c,d,col);
    44     if(d>mid[now])update(r[now],mid[now]+1,b,c,d,col);
    45     pushup(now,l[now],r[now]);
    46 }
    47 int getpos(int now,int a,int b,int len){
    48     int L=l[now],R=r[now];
    49     if(cov[now]!=2)pushdown(now,L,R);
    50     if(mx[L]>=len)return getpos(L,a,mid[now],len);
    51     else if(rmx[L]+lmx[R]>=len)return mid[now]-rmx[L]+1;
    52     else return getpos(R,mid[now]+1,b,len);
    53 }
    54 inline int read(){
    55     rx=getchar();ra=0;
    56     while(rx<'0'||rx>'9')rx=getchar();
    57     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    58 }
    59 int main(){
    60     n=read();m=read();
    61     build(1,n);
    62     for(i=1;i<=m;i++){
    63         id=read();L=read();
    64         if(id==1){
    65             if(mx[1]>=L){
    66                 pos=getpos(1,1,n,L);
    67                 printf("%d
    ",pos);
    68                 update(1,1,n,pos,pos+L-1,1);
    69             }else printf("0
    ");
    70         }else{
    71             R=read();
    72             update(1,1,n,L,L+R-1,0);
    73         }
    74     }
    75     return 0;
    76 }
    View Code

      1A感人TAT

    bzoj 1697: [Usaco2007 Feb]Cow Sorting牛排序

      置换群。。现在还是不会置换群QAQ。。。不过至少这题的题解看得懂QAQ。。。

      题解网上一坨。。因为poj里也有= =

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 using namespace std;
     7 const int maxn=10023;
     8 struct zs{
     9     short pos;
    10     int val;
    11 }a[maxn];
    12 short i,j,pos,n;
    13 ll mn,ans,nowmn,nowsum,len;
    14 bool u[maxn];
    15  
    16 bool cmp(zs a,zs b){
    17     return a.val<b.val;
    18 }
    19 int ra;char rx;
    20 inline int read(){
    21     rx=getchar();ra=0;
    22     while(rx<'0'||rx>'9')rx=getchar();
    23     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    24 }
    25 int main(){
    26     n=read();
    27     for(i=1;i<=n;i++)a[i].val=read(),a[i].pos=i;
    28     sort(a+1,a+1+n,cmp);mn=a[1].val;
    29     for(i=1;i<=n;i++)if(!u[i]){
    30         u[i]=1;nowmn=nowsum=a[i].val;len=1;
    31         for(pos=a[i].pos;!u[pos];pos=a[pos].pos){
    32             len++,nowsum+=(ll)a[pos].val,u[pos]=1;
    33             if(a[pos].val<nowmn)nowmn=a[pos].val;
    34         }
    35         ans+=nowsum+min((len-2)*nowmn,nowmn+(len+1)*mn);
    36     }
    37     printf("%lld
    ",ans);
    38     return 0;
    39 }
    View Code

    bzoj 1828: [Usaco2010 Mar]balloc 农场分配

      把各个请求按右端点从小到大排序。。然后直接依次能满足的就满足。。。这样就行了。。。。至于为什么这样子贪心是对的。。TAT

      设区间左右端点为l[],r[]...

      因为是按r排序的:如果当前区间插入后会影响到后面的某个区间的话,那么相比于那个被影响的区间,插入当前区间更优。

               并且在插入当前区间前我们已经尽量满足了r更小的区间,所以当前区间对之前的区间无影响。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=132333;
     7 struct zs{
     8     int l,r;
     9 }a[maxn];
    10 int mn[maxn<<1],l[maxn<<1],r[maxn<<1],mid[maxn<<1],tag[maxn<<1];
    11 int ra;char rx;
    12 int i,j,k,n,m,ans,tot;
    13   
    14 inline int read(){
    15     rx=getchar();ra=0;
    16     while(rx<'0'||rx>'9')rx=getchar();
    17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    18 }
    19 void build(int a,int b){
    20     int now=++tot;
    21     mid[now]=(a+b)>>1;
    22     if(a<b){
    23         l[now]=tot+1;build(a,mid[now]);
    24         r[now]=tot+1;build(mid[now]+1,b);
    25         if(mn[l[now]]<mn[r[now]])mn[now]=mn[l[now]];else mn[now]=mn[r[now]];
    26     }else mn[now]=read();
    27 }
    28 bool cmp(zs a,zs b){
    29     return a.r<b.r;
    30 }
    31 inline void pushdown(int now,int t){
    32     tag[l[now]]+=t;tag[r[now]]+=t;
    33     mn[l[now]]-=t;mn[r[now]]-=t;
    34     tag[now]=0;
    35 }
    36 int query(int now,int a,int b,int c,int d){
    37     if(c<=a&&d>=b)return mn[now];
    38     if(tag[now])pushdown(now,tag[now]);
    39     if(d<=mid[now])return query(l[now],a,mid[now],c,d);
    40     else if(c>mid[now])return query(r[now],mid[now]+1,b,c,d);
    41     else return min(query(l[now],a,mid[now],c,d),query(r[now],mid[now]+1,b,c,d));
    42 }
    43 void insert(int now,int a,int b,int c,int d){
    44     if(c<=a&&d>=b){tag[now]++;mn[now]--;return;}
    45     if(tag[now])pushdown(now,tag[now]);
    46     if(c<=mid[now])insert(l[now],a,mid[now],c,d);
    47     if(d>mid[now])insert(r[now],mid[now]+1,b,c,d);
    48     mn[now]=min(mn[l[now]],mn[r[now]]);
    49 }
    50 int main(){
    51     n=read();m=read();
    52     build(1,n);
    53     for(i=1;i<=m;i++)a[i].l=read(),a[i].r=read();
    54     sort(a+1,a+1+m,cmp);
    55     for(i=1;i<=m;i++)if(query(1,1,n,a[i].l,a[i].r)>0)ans++,insert(1,1,n,a[i].l,a[i].r);
    56     printf("%d
    ",ans);
    57     return 0;
    58 }
    View Code

    bzoj 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

      就是求后继节点的总数。。。因为整张图是由若干个基环内向树组成,所以可以用tarjan缩点后做。。。

      不过因为是基环内向树(同今年noipD1T2)。。从某个点开始一直走就会把它所连向的环走遍,也就起到了缩点的效果。。

      具体就开个栈记录一下当前路径,记录一个点是否在栈中。注意已经求出后继节点数的点就不用再走了.

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=100001;
     5 int to[maxn],ans[maxn],st[maxn];
     6 bool ins[maxn];
     7 int i,j,n,m,top,ed,len,tmp;
     8 char s[6];
     9 int ra;char rx;
    10 inline int read(){
    11     rx=getchar();ra=0;
    12     while(rx<'0'||rx>'9')rx=getchar();
    13     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    14 }
    15 inline void outx(int x){
    16     for(tmp=0;x;x/=10)s[tmp++]=x%10;
    17     for(register int i=tmp-1;i>=0;i--)putchar(s[i]+48);putchar('
    ');
    18 }
    19 int main(){
    20     n=read();
    21     for(i=1;i<=n;i++)to[i]=read();
    22     for(i=1;i<=n;i++)if(!ans[i]){
    23         ins[i]=ans[i]=1;st[top=1]=i;
    24         for(j=to[i];!ans[j]&&!ins[j];j=to[j])st[++top]=j,ins[j]=1;
    25         if(ins[j]){
    26             for(ed=j,j=top,len=1;st[j]!=ed;j--)len++;
    27             for(;top>=j;top--)ans[st[top]]=len,ins[st[top]]=0;
    28         }
    29         while(top)ans[st[top]]=1+ans[to[st[top]]],ins[st[top--]]=0;
    30     }
    31     for(i=1;i<=n;i++)outx(ans[i]);
    32     return 0;
    33 }
    View Code

    //之前弄了半天依然被踩在#2。。。。知道刚刚才想到一个布尔数组不用开才弄到200ms。。。再加了个输出优化瞬间就176ms了= =感人肺腑

      

    //为什么我每次用register int都更慢

    bzoj 1754: [Usaco2005 qua]Bull Math

      高精度乘法。。。。。。。。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int modd=10000;
     6 int a[23],b[23],ans[23],len;
     7 char s[44];
     8 short i,j;
     9 int main(){
    10     scanf("%s",s);a[0]=1;
    11     for(i=strlen(s),len=1;i;i--){
    12         a[a[0]]+=(s[i-1]-'0')*len;
    13         len*=10;if(len>=modd&&i>1)len=1,a[0]++;
    14     }
    15     scanf("%s",s);b[0]=1;
    16     for(i=strlen(s),len=1;i;i--){
    17         b[b[0]]+=(s[i-1]-'0')*len;
    18         len*=10;if(len>=modd&&i>1)len=1,b[0]++;
    19     }
    20     len=a[0]+b[0];
    21     for(i=1;i<=a[0];i++)for(j=1;j<=b[0];j++){
    22         ans[i+j-1]+=a[i]*b[j];
    23         if(ans[i+j-1]>=modd)ans[i+j]+=ans[i+j-1]/modd,ans[i+j-1]%=modd;
    24     }
    25     while(!ans[len]&&len>1)len--;
    26     printf("%d",ans[len]);
    27     for(i=len-1;i;i--){
    28         for(j=10;j<modd;j*=10)if(ans[i]<j)putchar('0');
    29         printf("%d",ans[i]);
    30     }printf("
    ");
    31     return 0;
    32 }
    View Code

    bzoj 1770: [Usaco2009 Nov]lights 燈

      高斯消元解异或方程组。。。。自由元就暴力枚举+最优性剪枝= =。。。

      话说自由元啊什么的一直不懂。。。数学方面以后再慢慢补吧(已经无数次这么说了TAT

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 short f[40][40],ans[40];
     6 int i,j,k,n,m,mn,a,b;
     7 int ra;char rx;
     8 inline int read(){
     9     rx=getchar();ra=0;
    10     while(rx<'0'||rx>'9')rx=getchar();
    11     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    12 }
    13 void gauss(){
    14     short i,j,k;
    15     for(i=1;i<=n;i++){
    16         for(j=i;j<=n&&!f[j][i];j++);if(j>n)continue;
    17         if(i!=j)for(k=1;k<=n+1;k++)swap(f[i][k],f[j][k]);
    18         for(j=1;j<=n;j++)if(i!=j&&f[j][i])
    19             for(k=1;k<=n+1;k++)f[j][k]^=f[i][k];
    20     }
    21 }
    22 void dfs(short now,int tot){
    23     if(tot>=mn)return;
    24     if(!now){
    25         mn=tot;return;
    26     }
    27     if(f[now][now]){
    28         short i;
    29         ans[now]=f[now][n+1];
    30         for(i=now+1;i<=n;i++)if(f[now][i])ans[now]^=ans[i];
    31         dfs(now-1,tot+ans[now]);
    32     }else{
    33         ans[now]=0;dfs(now-1,tot);
    34         ans[now]=1;dfs(now-1,tot+1);
    35     }
    36 }
    37 int main(){
    38     n=read();m=read();
    39     for(i=1;i<=n;i++)f[i][i]=f[i][n+1]=1;
    40     for(i=1;i<=m;i++)a=read(),b=read(),f[a][b]=f[b][a]=1;
    41     gauss();
    42     mn=1022223333;
    43     dfs(n,0);
    44     printf("%d
    ",mn);
    45     return 0;
    46 }
    View Code

      抄了黄学长代码。。捂脸

    bzoj 1691: [Usaco2007 Dec]挑剔的美食家

      有点像bzoj1828。。。都是两个限定条件,虽然具体有点不同= =

      把奶牛按要求最低价升序排序,牧草按价格升序排序。

      枚举牧草,每种牧草让可接受它的奶牛中,对新鲜度要求最高的奶牛吃。

      具体就是用平衡树维护可接受当前价格的奶牛(会越来越多)的要求新鲜度。。每种牧草按新鲜度在树中找一下前驱。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #define ll long long
     7 using namespace std;
     8 const int maxn=100233;
     9 const int inf=1002333333;
    10 struct gc{
    11     int c,v;
    12 }g[maxn],c[maxn];
    13  
    14 int t[maxn],l[maxn],r[maxn],rnd[maxn],sz[maxn];
    15 int i,j,k,n,m,tot,rt,num;
    16 ll ans;
    17  
    18 inline void lturn(int &x){
    19     int R=r[x];r[x]=l[R];l[R]=x;x=R;
    20 }
    21 inline void rturn(int &x){
    22     int L=l[x];l[x]=r[L];r[L]=x;x=L;
    23 }
    24 void insert(int &x,int val){
    25     if(!x){x=++tot;t[x]=val;rnd[x]=rand();sz[x]=1;//printf("! cow v:%d  in
    ",val);
    26             return;
    27     }
    28     if(val==t[x])sz[x]++;
    29      else if(val<t[x])
    30          {insert(l[x],val);
    31           if(rnd[l[x]]<rnd[x])rturn(x);
    32     }else{insert(r[x],val);
    33           if(rnd[r[x]]<rnd[x])lturn(x);
    34     }
    35 }
    36 void del(int &x,int val){
    37     if(t[x]==val){
    38         //printf("!  deleting %d   v:%d
    ",x,t[x]);
    39         if(sz[x]>1)sz[x]--;
    40         else if(!(l[x]&&r[x]))x=l[x]+r[x];//,printf("---->%d
    ",x);
    41         else if(rnd[l[x]]<rnd[r[x]]){rturn(x);del(x,val);}else {lturn(x);del(x,val);}
    42     }else if(val<t[x])del(l[x],val);else del(r[x],val);
    43 }
    44 int find(int x,int val){if(!x)return 0;
    45     if(t[x]>val)return find(l[x],val);else{
    46         int tmp=find(r[x],val);
    47         if(tmp)return tmp;else return t[x];
    48     }
    49 }
    50 inline void read(int &ans){
    51     char x=getchar();
    52     while(x<'0'||x>'9')x=getchar();
    53     while(x>='0'&&x<='9')ans*=10,ans+=x-48,x=getchar();
    54 }
    55 bool cmp(gc a,gc b){return a.c<b.c;}
    56 int main(){
    57     read(n);read(m);
    58     if(m<n){printf("-1
    ");return 0;};
    59     for(i=1;i<=n;i++)read(c[i].c),read(c[i].v);
    60     for(i=1;i<=m;i++)read(g[i].c),read(g[i].v);
    61     sort(c+1,c+1+n,cmp);sort(g+1,g+1+m,cmp);j=rt=0;
    62     for(i=1;i<=m&&m-i+1>=n-num&&num<n;i++){
    63         while(j<n&&c[j+1].c<=g[i].c)j++,insert(rt,c[j].v);
    64         int val=find(rt,g[i].v);
    65         //printf("grass%d(%d %d)  be eaten by cow v:%d(%d %d)
    ",i,g[i].c,g[i].v,val,,c[pos].v);
    66         if(val)
    67             num++,ans+=(ll)g[i].c,del(rt,val);
    68                                 //,printf("%d(%d %d) eats  %d(%d %d)
    ",pos,c[pos].c,c[pos].v,i,g[i].c,g[i].v);
    69     }
    70     if(num==n)
    71     printf("%lld
    ",ans);else printf("-1
    ");
    72     return 0;
    73 }
    View Code

      手打treap比调stl的慢= =

    bzoj 1753: [Usaco2005 qua]Who's in the Middle

      如题。。。。。。。。。。。。。。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=10001;
     7 int a[maxn],n,i;
     8  
     9 int ra;char rx;
    10 inline int read(){
    11     rx=getchar();ra=0;
    12     while(rx<'0'||rx>'9')rx=getchar();
    13     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    14 }
    15 int main(){
    16     n=read();for(i=1;i<=n;i++)a[i]=read();
    17     sort(a+1,a+1+n);
    18     printf("%d
    ",a[(n+1)>>1]);
    19     return 0;
    20 }
    View Code

    加了快速读入比没加的慢是什么情况= =

    bzoj 1574: [Usaco2009 Jan]地震损坏Damage

      就是说对于报告的每个点,都要找到一圈点把它围起来(与1点阻断)。。显然(又是看题解才知道的QAQ)这一圈点就是那个点相邻的所有点(当然相邻点也可能是被报告的点,但总之这些点都无法到达了)。。

      因为圈内的点都无法到达,我们要使得圈上及圈内的点最少。。所以圈越小越好。。

      把每个报告的点的相邻节点都设为不可通过,最后统计下还能到达的点的数目就好。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 struct zs{
     6     short too;
     7     int pre;
     8 }e[200233];
     9 int last[30233],dl[30023];
    10 bool dead[30233];
    11 int i,j,k,n,m,a,b,p,l,r,now,tot;
    12 int ra;char rx;
    13 inline int read(){
    14     rx=getchar();ra=0;
    15     while(rx<'0'||rx>'9')rx=getchar();
    16     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    17 }
    18 inline void insert(short a,short b){
    19     e[++tot].too=b;e[tot].pre=last[a];last[a]=tot;
    20     e[++tot].too=a;e[tot].pre=last[b];last[b]=tot;
    21 }
    22 int main(){
    23     n=read();m=read();p=read();
    24     for(i=1;i<=m;i++)a=read(),b=read(),insert(a,b);
    25     for(i=1;i<=p;i++){
    26         a=read();dead[a]=1;
    27         for(j=last[a];j;j=e[j].pre)dead[e[j].too]=1;
    28     }
    29     l=0;if(!dead[1])r=1;dl[1]=1;dead[1]=1;
    30     while(l<r){
    31         now=dl[++l];
    32         for(i=last[now];i;i=e[i].pre)if(!dead[e[i].too])dead[e[i].too]=1,dl[++r]=e[i].too;
    33     }
    34     printf("%d
    ",n-r);
    35     return 0;
    36 }
    View Code

    bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

      DPhttp://www.cnblogs.com/czllgzmzl/p/5066443.html

    bzoj 1710: [Usaco2007 Open]Cheappal 廉价回文

      因为最后要形成回文串。。。对于回文串来说删一个字母和 在对应位置添加一个同样的字母是等价的= =

      所以把一个字母和谐掉的代价是min(删除该字母费用,添加该字母费用)。。(记为cost[])

      接下来就是区间dp了。。。f[i][j]表示把原字符串中第i个~第j个字母变成回文串的最小代价。。原字符串为s

      f[i][j]=min{

        f[i][j-1]+cost[s[j]],f[i+1][j]+cost[s[i]],

        f[i+1][j-1],(s[i]==s[j])

      }最后答案就是f[1][m]

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=2033;
     6 char s[maxn],c[27];
     7 short cost[233],tmp;
     8 int f[maxn][maxn];
     9 short i,j,k,n,m,len;
    10 short ra;char rx,trx;
    11 inline short read(){
    12     rx=getchar();ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 int main(){
    17     n=read();m=read();
    18     for(s[1]=getchar();s[1]<'a'||s[1]>'z';s[1]=getchar());
    19     for(i=2;i<=m;i++)s[i]=getchar();
    20     for(i=1;i<=n;i++){
    21         for(trx=getchar();trx<'a'||trx>'z';trx=getchar());
    22         tmp=read();cost[trx]=read();
    23         if(tmp<cost[trx])cost[trx]=tmp;
    24     }
    25     for(len=2;len<=m;len++)for(i=m-len+1,j=m;i;i--,j--)
    26         if(s[i]==s[j])f[i][j]=f[i+1][j-1];
    27         else if(cost[s[j]]+f[i][j-1]<cost[s[i]]+f[i+1][j])f[i][j]=cost[s[j]]+f[i][j-1];
    28         else f[i][j]=cost[s[i]]+f[i+1][j];
    29     printf("%d
    ",f[1][m]);
    30     return 0;
    31 }
    View Code

    bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名

      善用stl。。。善调bitset。。。

      按给出的大小关系建图。。求出每头牛i能确定的比它小的奶牛的数量num[i],答案就是 总对数-已知的关系对数。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<bitset>
     5 using namespace std;
     6 short too[1008][1008];
     7 bool u[1008],map[1008][1008];
     8 bitset<1008>a[1008];
     9 int i,j,k,n,m;
    10 int ra;char rx;
    11 inline int read(){
    12     rx=getchar();ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 void dfs(int x){
    17     u[x]=1;
    18     for(short i=too[x][0];i;i--)if(!u[too[x][i]])dfs(too[x][i]),a[x]|=a[too[x][i]];
    19     else a[x]|=a[too[x][i]];
    20 }
    21 int main(){
    22     n=read();m=read();
    23     for(i=1;i<=m;i++){
    24         j=read(),k=read();
    25         if(!map[j][k])map[j][k]=1,too[j][++too[j][0]]=k;
    26     }
    27     for(i=1;i<=n;i++)a[i][i]=1;
    28     for(i=1;i<=n;i++)if(!u[i])dfs(i);
    29     for(j=(n-1)*n/2+n,i=1;i<=n;i++)j-=a[i].count();
    30     printf("%d
    ",j);
    31     return 0;
    32 }
    View Code

    为啥同样是调bitset我就慢了这么多TAT

    bzoj 1578: [Usaco2009 Feb]Stock Market 股票市场

      看了老司机的题解。。。http://www.cnblogs.com/JSZX11556/p/4664348.html

      引用:“我们假设每天买完第二天就卖掉( 不卖出也可以看作是卖出后再买入 ), 这样就是变成了一个完全背包问题了, 股票价格为体积, 第二天的股票价格 - 今天股票价格为价值.... 然后就一天一天dp...”。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxt=500012;
     6 int map[11][51],val,cost;
     7 int f[maxt];
     8 int i,j,k,n,m,T,nowt;
     9  
    10 int ra;char rx;
    11 inline int read(){
    12     rx=getchar();ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 int main(){
    17     n=read();T=read();m=read();
    18     for(i=0;i<n;i++)for(j=0;j<T;j++)map[j][i]=read();
    19     for(nowt=1;nowt<T;nowt++){
    20         if(nowt>1)memset(f,0,(m+1)<<2);
    21         for(i=0;i<n;i++){
    22             val=map[nowt][i]-map[nowt-1][i];cost=map[nowt-1][i];
    23             if(val<=0)continue;
    24             for(j=cost;j<=m;j++)if(f[j-cost]+val>f[j])f[j]=f[j-cost]+val;
    25         }
    26         m+=f[m];
    27     }
    28     printf("%d
    ",m);
    29     return 0;
    30 }
    View Code

    bzoj 1598: [Usaco2008 Mar]牛跑步

      求第k短路。。看了kpm大爷的代码才知道可以懒出新境界。。。

      用优先队列维护spfa的队列(其实就变成了堆优化的dij)。。一个点出队k次时我们就得出了k短路。。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 const int maxn=1002;
     7 struct zs{
     8     int dis,pos;
     9 };
    10 struct edge{
    11     int too,pre,dis;
    12 }e[10023];
    13 int dis[maxn],last[maxn],sumk[maxn];
    14 int i,j,k,n,m,size,K,a;
    15 priority_queue<zs>q;
    16 bool operator <(zs a,zs b){
    17     return a.dis>b.dis;
    18 }
    19  
    20 int ra;char rx;
    21 inline int read(){
    22     rx=getchar();ra=0;
    23     while(rx<'0'||rx>'9')rx=getchar();
    24     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    25 }
    26 int main(){
    27     n=read();m=read();K=read();
    28     for(i=1;i<=m;i++){
    29         a=read();e[i].too=read();e[i].dis=read();
    30         e[i].pre=last[a];last[a]=i;
    31     }zs tmp;
    32     size=1;tmp.pos=n;tmp.dis=0;q.push(tmp);
    33     while(size&&sumk[1]<K){
    34         i=q.top().pos;j=q.top().dis;size--;q.pop();
    35         if(sumk[i]>=K)continue;
    36         sumk[i]++;if(i==1){printf("%d
    ",j);}
    37         for(i=last[i];i;i=e[i].pre)tmp.pos=e[i].too,tmp.dis=j+e[i].dis,q.push(tmp),size++;
    38     }
    39     for(i=K-sumk[1];i;i--)puts("-1
    ");
    40     return 0;
    41 }
    View Code

    bzoj 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛

      终于是傻逼题了。。。没有上司的舞会。树形dp,f[i][0]表示以i为根节点,i不选,能选的最多点数,f[i][1]表示以i为根节点,i选,能选的最多点数。

      f[i][0]=sum{ max(f[j][0],f[j][1]) },(j是i的儿子);f[i][1]=sum{ f[j][0] },(j是i的儿子)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=50023;
     6 struct zs{
     7     int too,pre;
     8 }e[maxn<<1];
     9 int last[maxn],f[maxn][2];
    10 int i,j,n,m,tot,a,b;
    11 int ra;char rx;
    12 inline int read(){
    13     rx=getchar();ra=0;
    14     while(rx<'0'||rx>'9')rx=getchar();
    15     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    16 }
    17 void dfs(int x,int fa){
    18     f[x][1]=1;
    19     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa){
    20         dfs(e[i].too,x);
    21         if(f[e[i].too][0]>f[e[i].too][1])f[x][0]+=f[e[i].too][0];else f[x][0]+=f[e[i].too][1];
    22         f[x][1]+=f[e[i].too][0];
    23     }
    24 }
    25 int main(){
    26     n=read();
    27     for(i=1;i<n;i++){
    28         a=read();b=read();e[++tot].too=b;e[tot].pre=last[a];last[a]=tot;
    29         e[++tot].too=a;e[tot].pre=last[b];last[b]=tot;
    30     }
    31     dfs(1,0);
    32     printf("%d
    ",max(f[1][0],f[1][1]));
    33     return 0;
    34 }
    View Code

    bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

      和bzoj4236那题思路一样。。。求得各种颜色数的前缀和,并差分。。如果两不同位置上差分后的结果相等,就说明这两个位置之间各种颜色数量相等。

      可以上hash。。。然而卡常无力被稳稳地踩了TAT

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=100003;
     7 struct zs{
     8     int pos;
     9     unsigned int v;
    10 }a[maxn];
    11 int nownum[31],two[31];
    12 bool u[maxn];
    13 int i,j,k,n,m,kk,x,ans;
    14 bool same;
    15 int ra;char rx;
    16 inline int read(){
    17     rx=getchar();ra=0;
    18     while(rx<'0'||rx>'9')rx=getchar();
    19     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    20 }
    21 bool cmp(zs a,zs b){
    22     return a.v<b.v||(a.v==b.v&&a.pos<b.pos);
    23 }
    24 int main(){
    25     n=read();k=read();two[1]=1;
    26     for(i=1;i<k;i++)two[i+1]=two[i]<<1;
    27     for(i=1;i<=n;i++){
    28         x=read();
    29         for(j=1;j<=k;j++)if(x&two[j])nownum[j]++;
    30         for(j=1;j<k;j++)//a[i].num[j]=nownum[j]-nownum[j+1],
    31             a[i].v*=233,a[i].v+=nownum[j]-nownum[j+1];
    32         a[i].pos=i;
    33     }
    34     n++;
    35     sort(a+1,a+1+n,cmp);
    36     for(i=1;i<=n;){
    37         for(j=i+1;j<=n&&a[i].v==a[j].v;j++);
    38         j--;
    39         if(a[j].pos-a[i].pos>ans)ans=a[j].pos-a[i].pos;
    40         i=j+1;
    41     }
    42     printf("%d
    ",ans);
    43     return 0;
    44 }
    View Code

    bzoj 1704: [Usaco2007 Mar]Face The Right Way 自动转身机

      如果K已经确定的话,可以O(n)求出最小判断次数M:从前往后扫一遍,如果一个点i上奶牛朝后站着,就把i~i+k-1头奶牛都转过来。因为此时不转的话以后就转不了了。。。

      注意无解的判定。。。如果第i头奶牛朝后站着且i+k>n(就是没有k头奶牛可以转了)就无解。。。

      区间修改,单点查询。。。这个可以用差分。。因为只有朝前和朝后两种,就直接异或一下就好了。时间复杂度O(n*k)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=5005;
     6 bool now[maxn],nowsum;
     7 int i,j,k,n,m,nowans,ans;
     8 bool mp[maxn];
     9 char rx;
    10 int main(){
    11     scanf("%d",&n);
    12     for(i=1;i<=n;i++){
    13         for(rx=getchar();rx!='F'&&rx!='B';rx=getchar());
    14         mp[i]^=(rx=='B');
    15         if(rx=='B')mp[i+1]^=1,ans++;
    16     }
    17     k=1;
    18     for(i=2;i<=n;i++){
    19         memcpy(now,mp,(n+1));nowans=nowsum=0;
    20         for(j=1;j<=n&&nowans<ans;j++){
    21             nowsum^=now[j];
    22             if(nowsum&&j+i>n+1){nowans=102333333;break;}
    23             if(nowsum)nowsum^=1,now[j+i]^=1,nowans++;
    24         }
    25         if(nowans<ans)ans=nowans,k=i;
    26     }
    27     printf("%d %d
    ",k,ans);
    28     return 0;
    29 }
    View Code

    bzoj 1776: [Usaco2010 Hol]cowpol 奶牛政坛

      由题解可得(TAT)结论:某政党内部的最长路径一定有一个端点是政党内最深的一个点。。毕竟树的直径也有一个端点在叶子节点上?

      先一遍dfs求出每个政党最深的点,然后求它和所在政党其他点的距离的最大值。。树上两点间的距离dis(i,j)=depth[i]+depth[j]-depth[lca(i,j)]*2。。

      总时间复杂度O(nlogn)...求lca部分试了倍增和链剖两种。。。。代码长度差不多但是倍增慢多了QAQ

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=200233;
     6 const int maxdep=20;
     7 struct zs{
     8     int too,pre;
     9 }e[maxn<<1],map[maxn];
    10 int last[maxn],dep[maxn],last1[maxn],mxpos[maxn],mxdep[maxn],bel[maxn],belong[maxn],size[maxn],fa[maxn];
    11 int i,j,k,n,m,tot1,a,tot,K,b,ans,rt;
    12   
    13 int ra;char rx;
    14 inline int read(){
    15     rx=getchar();ra=0;
    16     while(rx<'0'||rx>'9')rx=getchar();
    17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    18 }
    19 inline void insert(int a,int b){
    20     map[++tot1].too=b;map[tot1].pre=last1[a];last1[a]=tot1;
    21 }
    22 void dfs(int x,int pre){
    23     int i;size[x]=1;dep[x]=dep[pre]+1;fa[x]=pre;
    24     if(dep[x]>mxdep[bel[x]])mxdep[bel[x]]=dep[x],mxpos[bel[x]]=x;
    25     insert(bel[x],x);
    26     for(i=last[x];i;i=e[i].pre)if(e[i].too!=pre)
    27         dfs(e[i].too,x),size[x]+=size[e[i].too];
    28 }
    29 void dfs2(int x,int chain){
    30     int i,k=0;belong[x]=chain;
    31     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&size[e[i].too]>size[k])k=e[i].too;
    32     if(!k)return;
    33     dfs2(k,chain);
    34     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=k)dfs2(e[i].too,e[i].too);
    35 }
    36 inline int getlcadep(int a,int b){
    37     for(;belong[a]!=belong[b];a=fa[belong[a]])if(dep[belong[a]]<dep[belong[b]])swap(a,b);
    38     if(dep[a]<dep[b])return dep[a];else return dep[b];
    39 }
    40 int main(){
    41     n=read();K=read();
    42     for(i=1;i<=n;i++){
    43         bel[i]=read();a=read();if(!a){rt=i;continue;}
    44         e[++tot].too=i;e[tot].pre=last[a];last[a]=tot;
    45         e[++tot].too=a;e[tot].pre=last[i];last[i]=tot;
    46     }rt=n<4?n>>1:n>>2;
    47     dfs(rt,0);dfs2(rt,rt);
    48     for(i=1;i<=K;i++){
    49         ans=0;
    50         for(k=mxpos[i],j=last1[i];j;j=map[j].pre)ans=max(ans,dep[k]+dep[map[j].too]-(getlcadep(k,map[j].too)<<1));
    51         printf("%d
    ",ans);
    52     }
    53     return 0;
    54 }
    55 //链剖
    View Code链剖
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=200233;
     6 const int maxdep=20;
     7 struct zs{
     8     int too,pre;
     9 }e[maxn<<1],map[maxn];
    10 int last[maxn],depth[maxn],fa[maxn][maxdep],dep[maxn],last1[maxn],mxpos[maxn],mxdep[maxn],bel[maxn];
    11 int i,j,k,n,m,tot1,a,tot,K,b,ans,rt;
    12   
    13 int ra;char rx;
    14 inline int read(){
    15     rx=getchar();ra=0;
    16     while(rx<'0'||rx>'9')rx=getchar();
    17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    18 }
    19 inline void insert(int a,int b){
    20     map[++tot1].too=b;map[tot1].pre=last1[a];last1[a]=tot1;
    21 }
    22 void dfs(int x,int pre){
    23     int i;
    24     dep[x]=dep[pre]+1;depth[x]=depth[pre];
    25     if((dep[x]&(-dep[x]))==dep[x])depth[x]++;
    26     if(dep[x]>mxdep[bel[x]])mxdep[bel[x]]=dep[x],mxpos[bel[x]]=x;
    27     insert(bel[x],x);//printf("%d %d  %d %d
    ",x,bel[x],dep[x],depth[x]);
    28       
    29     for(i=1;i<=depth[x];i++)fa[x][i]=fa[fa[x][i-1]][i-1];
    30     for(i=last[x];i;i=e[i].pre)if(e[i].too!=pre)
    31         fa[e[i].too][0]=x,dfs(e[i].too,x);
    32 }
    33 inline int getlca(int a,int b){
    34     int i;
    35     if(dep[a]<dep[b])swap(a,b);
    36     for(i=depth[a];i>=0;i--)if(dep[fa[a][i]]>=dep[b])a=fa[a][i];
    37     if(a!=b){
    38         for(i=depth[a];i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
    39         a=fa[a][0];
    40     }
    41     return a;
    42 }
    43 int main(){
    44     n=read();K=read();
    45     for(i=1;i<=n;i++){
    46         bel[i]=read();a=read();if(!a){rt=i;continue;}
    47         e[++tot].too=b=i;e[tot].pre=last[a];last[a]=tot;
    48         e[++tot].too=a;e[tot].pre=last[b];last[b]=tot;
    49     }depth[0]=-1;
    50     dfs(rt,0);
    51     for(i=1;i<=K;i++){
    52         ans=0;
    53         for(k=mxpos[i],j=last1[i];j;j=map[j].pre)ans=max(ans,dep[k]+dep[map[j].too]-(dep[getlca(k,map[j].too)]<<1));
    54         printf("%d
    ",ans);
    55     }
    56     return 0;
    57 }
    58 //倍增
    View Code

    bzoj 1700: [Usaco2007 Jan]Problem Solving 解题

      DP。。http://www.cnblogs.com/czllgzmzl/p/5068024.html

    bzoj 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛

      傻逼题。。二分答案+判定。。。。每次二分出一个答案mid后,贪心的划分,看一下能不能划出C段

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=100001;
     7 int a[maxn];
     8 int i,num,n,m,l,r,mid,pre;
     9 int ra;char rx;
    10 inline int read(){
    11     rx=getchar();ra=0;
    12     while(rx<'0'||rx>'9')rx=getchar();
    13     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    14 }
    15 int main(){
    16     n=read();m=read();
    17     for(i=1;i<=n;i++)a[i]=read();
    18     sort(a+1,a+1+n);
    19     if(m==2){printf("%d
    ",a[n]-a[1]);return 0;}
    20     if(m==n){
    21         for(l=a[n]-a[1],i=1;i<n;i++)if(a[i+1]-a[i]<l)l=a[i+1]-a[i];
    22         printf("%d
    ",l);return 0;
    23     }
    24     l=1;r=(a[n]-a[1])/(m-1);
    25     while(l<r){
    26         mid=(l+r+1)>>1;num=1;pre=a[1];
    27         for(i=2;i<=n;i++)if(a[i]-pre>=mid)pre=a[i],num++;
    28         if(num>=m)l=mid;else r=mid-1;
    29     }
    30     printf("%d
    ",l);
    31     return 0;
    32 }
    View Code

    bzoj 1741: [Usaco2005 nov]Asteroids 穿越小行星群

      二分图最大匹配。。。存在小行星(i,j),连一条i到j+n的边。

      dinic比匈牙利还是略慢。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=505;
     6 struct zs{
     7     int too,pre;
     8     bool flow;
     9 }e[23333];
    10 int last[maxn<<1],u[maxn<<1],dl[maxn<<1];
    11 short dis[maxn<<1];
    12 int i,j,k,n,m,tot,s,t,a,b,ans;
    13 int ra;char rx;
    14 inline int read(){
    15     rx=getchar();ra=0;
    16     while(rx<'0'||rx>'9')rx=getchar();
    17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    18 }
    19 inline void insert(int a,int b){
    20     e[++tot].too=b;e[tot].flow=1;e[tot].pre=last[a];last[a]=tot;
    21     e[++tot].too=a;e[tot].flow=0;e[tot].pre=last[b];last[b]=tot;
    22 }
    23 inline bool bfs(){
    24     memset(dis,255,(t+1)<<1);
    25     int l=0,r=1,now,i;dl[1]=s;dis[s]=0;
    26     while(l<r){
    27         now=dl[++l];
    28         for(i=last[now];i;i=e[i].pre)if(dis[e[i].too]==-1&&e[i].flow)
    29             dis[e[i].too]=dis[now]+1,dl[++r]=e[i].too;
    30     }
    31     return dis[t]!=-1;
    32 }
    33 int dfs(int x,int mx){
    34     if(x==t)return mx;
    35     int i,used=0,w;
    36     for(i=last[x];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==dis[x]+1){
    37         w=dfs(e[i].too,1);if(w){
    38             e[i].flow=0;;e[i^1].flow=1;
    39             used++;if(used==mx)return mx;
    40         }
    41     }
    42     dis[x]=-1;return used;
    43 }
    44 int main(){tot=1;
    45     n=read();m=read();s=0;t=n+n+1;
    46     for(i=1;i<=n;i++)insert(s,i),insert(i+n,t);
    47     for(i=1;i<=m;i++)
    48         a=read(),b=read(),insert(a,b+n);
    49     while(bfs())ans+=dfs(s,233333333);
    50     printf("%d
    ",ans);
    51     return 0;
    52 }
    View Code

    bzoj 1705: [Usaco2007 Nov]Telephone Wire 架设电话线

      DPhttp://www.cnblogs.com/czllgzmzl/p/5068259.html

    bzoj 1783: [Usaco2010 Jan]Taking Turns

      有点算博弈相关?http://www.cnblogs.com/czllgzmzl/p/5069730.html

  • 相关阅读:
    Azure SQL Database (1) 用户手册
    Windows Azure Web Site (17) Azure Web Site 固定公网IP地址
    MongoDB数据文件内部结构
    压缩 MongoDB 的数据文件
    服务器如何选择网络带宽(转)
    刀片服务器和磁盘阵列卡(RAID)技术---永和维护(转)
    Solr打分出错
    Solr添加SolrDocument报错
    解决Windows Git Bash中文乱码问题
    HAProxy的独门武器:ebtree
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5074158.html
Copyright © 2020-2023  润新知