USACO 刷题记录bzoj

bzoj 1606: [Usaco2008 Dec]Hay For Sale 购买干草——背包

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int h,n,f[50007],k;
int main()
{
    h=read(); n=read();
    f[0]=1;
    for(int i=1;i<=n;i++){
        k=read();
        for(int j=h;j>=k;j--) if(f[j-k]) f[j]=1;
    }
    for(int i=h;i>=0;i--)if(f[i]){printf("%d\n",i); break;}
    return 0;
}
View Code

 bzoj 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头——筛数

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,f[1000007],v[100007],ans[1000007];
int main()
{
    n=read();
    for(int i=1;i<=n;i++) v[i]=read(),f[v[i]]++;
    for(int i=1;i<=(int)1e6;i++)if(f[i]){
        for(int j=i;j<=(int)1e6;j+=i) if(f[j]) ans[j]+=f[i];
    }
    for(int i=1;i<=n;i++) printf("%d\n",ans[v[i]]-1);
    return 0;
}
View Code

 bzoj 1597: [Usaco2008 Mar]土地购买——斜率优化dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=50007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL x[M],y[M],f[M];
int q[M],n,tot;
struct node{LL x,y;}a[M];
bool cmp(node a,node b){return a.x!=b.x?a.x<b.x:a.y<b.y;}
double slop(int a,int b){return (double)(f[b]-f[a])/(y[a+1]-y[b+1]);}
int main()
{
    n=read();
    for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++){
        while(tot&&y[tot]<=a[i].y) tot--;
        x[++tot]=a[i].x; y[tot]=a[i].y;
    }
    int head=0,tail=0;
    for(int i=1;i<=tot;i++){
        while(head<tail&&slop(q[head],q[head+1])<x[i]) head++;
        int v=q[head];
        f[i]=f[v]+y[v+1]*x[i];
        while(head<tail&&slop(q[tail-1],q[tail])>slop(q[tail],i)) tail--;
        q[++tail]=i;
    }
    printf("%lld\n",f[tot]);
    return 0;
}
View Code

 bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队 ——zkw版

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1<<19,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,q,l,r;
int mx[N<<1],mn[N<<1];
int push_ans(int l,int r){
    int mx1=0,mn1=inf;
    for(l+=N-1,r+=N+1;r-l!=1;l>>=1,r>>=1){
        if(~l&1) mx1=max(mx1,mx[l^1]),mn1=min(mn1,mn[l^1]);
        if(r&1)     mx1=max(mx1,mx[r^1]),mn1=min(mn1,mn[r^1]);
    }
    return mx1-mn1;
}
int main()
{
    n=read(); q=read();
    for(int i=1;i<=n;i++) mx[N+i]=mn[N+i]=read();
    for(int i=N-1;i;i--) mx[i]=max(mx[i<<1],mx[i<<1^1]),mn[i]=min(mn[i<<1],mn[i<<1^1]);
    for(int i=1;i<=q;i++){
        l=read(); r=read();
        printf("%d\n",push_ans(l,r));
    }
    return 0;
}
View Code

 bzoj 1602: [Usaco2008 Oct]牧场行走——lca

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e3+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int vis[M],d[M],q[M];
int n,k,first[M],cnt;
struct node{int to,w,next;}e[2*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,w,first[a]}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
void push_ans(int k){
    int head=0,tail=1;
    q[0]=k; vis[k]=1;
    while(head!=tail){
        int x=q[head++];
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(!vis[now]){
                vis[now]=1;
                d[now]=d[x]+e[i].w;
                q[tail++]=now;
            }
        }
    }
}
int main()
{
    int x,y,w;
    n=read(); k=read();
    for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    for(int i=1;i<=k;i++){
        x=read(); y=read();
        memset(vis,0,sizeof(vis));
        memset(d,0,sizeof(d));
        push_ans(x);
        printf("%d\n",d[y]);
    }
    return 0;
}
View Code

 bzoj 1610: [Usaco2008 Feb]Line连线游戏——几何

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int M=257;
bool pd(double x,double y){return fabs(x-y)<1e-7;}
int n,cnt,ans;
double x[M],y[M],a[M*M];
bool cmp(double x,double y){return x<y;}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]);
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++){
            if(!pd(x[i],x[j])) a[++cnt]=(y[i]-y[j])/(x[i]-x[j]);
            else ans=1;
        }
    sort(a+1,a+1+cnt,cmp);
    if(cnt>=1) ans++;
    for(int i=2;i<=cnt;i++) if(!pd(a[i],a[i-1])) ans++;
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 ——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=350007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,c[M],f[M][4],ans=inf;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) c[i]=read();
    memset(f,0x3f,sizeof(f));
    f[0][1]=f[0][2]=f[0][3]=0;
    for(int k=1;k<=n;k++)
        for(int i=1;i<=3;i++){
            for(int j=1;j<=i;j++) f[k][i]=min(f[k][i],f[k-1][j]);
            if(i!=c[k]) f[k][i]++;
        }
    for(int i=1;i<=3;i++) ans=min(ans,f[n][i]);
    memset(f,0x3f,sizeof(f));
    f[n+1][1]=f[n+1][2]=f[n+1][3]=0;
    for(int k=n;k>=1;k--)
        for(int i=1;i<=3;i++){
            for(int j=1;j<=i;j++) f[k][i]=min(f[k][i],f[k+1][j]);
            if(i!=c[k]) f[k][i]++;
        }
    for(int i=1;i<=3;i++) ans=min(ans,f[1][i]);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1625: [Usaco2007 Dec]宝石手镯——01背包

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=3507,N=15007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,c[M],w[M],f[N];
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) c[i]=read(),w[i]=read();
    for(int i=1;i<=n;i++)
        for(int j=m;j>=c[i];j--) f[j]=max(f[j],f[j-c[i]]+w[i]);
    printf("%d\n",f[m]);
    return 0;
}
View Code

 bzoj 1617: [Usaco2008 Mar]River Crossing渡河问题——简单dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int M=5507,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,f[M],w[M],s[M];
int main()
{
    n=read(); s[0]=read();
    for(int i=1;i<=n;i++) w[i]=read();
    for(int i=1;i<=n;i++) s[i]=s[i-1]+w[i];
    for(int i=1;i<=n;i++){
        f[i]=inf;
        for(int j=1;j<=i;j++) f[i]=min(f[i],f[i-j]+s[j]+s[0]);
    }
    printf("%d\n",f[n]-s[0]);
    return 0;
}
View Code

 bzoj  1650: [Usaco2006 Dec]River Hopscotch 跳石子——二分

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=55007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int L,n,m,s[M];
bool check(int mx){
    int cnt=0,sum=0;
    for(int i=1;i<=n;i++){
        if(s[i]-sum<=mx) cnt++;
        else sum=s[i];
    }
    return cnt<=m;
}
int main()
{
    L=read(); n=read(); m=read();
    for(int i=1;i<=n;i++) s[i]=read();
    s[++n]=L;
    sort(s+1,s+1+n);
    int l=0,r=L+1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) l=mid+1;
        else r=mid-1;
    }printf("%d\n",l);
    return 0;
}
View Code

 bzoj 2718: [Violet 4]毕业旅行——二分图匹配+最大反链

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=557,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans,n,m,S,T,f[M][M];
int vis[M],d[M],first[M],cur[M],cnt=1;
struct node{int to,next,flow;}e[M*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;};
void insert(int a,int b){ins(a,b,1); ins(b,a,0);}
void floyd(){
    for(int k=1;k<=n;k++)
     for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
       f[i][j]|=f[i][k]&f[k][j];
    for(int i=1;i<=n;i++) f[i][i]=0;
}
queue<int>q;
int bfs(){
    memset(d,-1,sizeof(d));
    q.push(S); d[S]=0; 
    while(!q.empty()){
        int x=q.front(); q.pop(); 
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now);
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||a==0) return a;
    int f,flow=0;
    for(int& i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(e[i].flow&&d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){
            e[i].flow-=f; e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int main()
{
    int x,y;
    n=read(); m=read(); ans=n;
    S=0; T=2*n+1;
    for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1;
    floyd();
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      if(f[i][j]) insert(i,j+n);
    for(int i=1;i<=n;i++) insert(S,i),insert(i+n,T);
    while(bfs()){
        for(int i=S;i<=T;i++) cur[i]=first[i];
        ans-=dfs(S,inf);
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1613: [Usaco2007 Jan]Running贝茜的晨练计划——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,w[M];
int f[M][1007];
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) w[i]=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) f[i][j]=f[i-1][j-1]+w[i];
        f[i][0]=f[i-1][0];
        for(int j=1;j<=m;j++) if(i>j) f[i][0]=max(f[i][0],f[i-j][j]);
    }
    printf("%d\n",f[n][0]);
    return 0;
}
View Code

 bzoj 1230: [Usaco2008 Nov]lites 开关灯——线段树

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1<<18;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m;
int k,L,R;
struct node{
    node *lc,*rc;
    int l,r,mid,sum,h,sz;
    void pr(){sum=sz-sum; h^=1;}
    void up(){sum=lc->sum+rc->sum;}
    void down(){h=0; lc->pr(); rc->pr();}
    void modify(){
        if(L<=l&&r<=R) return pr();
        if(h) down();
        if(L<=mid) lc->modify();
        if(R>mid) rc->modify();
        up();
    }
    int query(){
        if(L<=l&&r<=R) return sum;
        if(h) down();
        int tot=0;
        if(L<=mid) tot+=lc->query();
        if(R>mid)  tot+=rc->query();
        return tot;
    }
    node*build(int L,int R);
}tr[M],*np=tr+1;
node*node::build(int L,int R){
    l=L; r=R; sz=R-L+1;
    if(L<R){
        mid=(L+R)>>1;
        lc=++np;
        lc->build(L,mid);
        rc=++np;
        rc->build(mid+1,R);
    }
}
int main(){
    n=read(); m=read();
    tr[1].build(1,n);
    for(int i=1;i<=m;i++){
        k=read(); L=read(); R=read();
        if(!k) tr[1].modify();
        else if(k)  printf("%d\n",tr[1].query());
    }
    return 0;
}
View Code

 bzoj1600 1600: [Usaco2008 Oct]建造栅栏——简单dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n;
int f[15][2507];
int main()
{
    n=read();
    f[0][0]=1; 
    int mx=(n+1)/2-1;
    for(int k=1;k<=4;k++)
     for(int i=1;i<=n;i++)
      for(int j=1;j<=min(i,mx);j++)
          f[k][i]+=f[k-1][i-j];
    printf("%d\n",f[4][n]);
    return 0;
}
View Code

 bzoj 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛

n^3算法 用的bitset可能快点n^3/32吧 暂时没有更优的方法

#include<cstdio>
#include<bitset>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m;
bitset<107> f[107];
int main(){
    int x,y;
    n=read(); m=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1;
    for(int k=1;k<=n;++k)
        for(int i=1;i<=n;i++) if(f[i][k]) f[i]|=f[k];
    int res=0;
    for(int i=1;i<=n;++i){
        int sum=1;
        for(int j=1;j<=n;j++) sum+=f[i][j]|f[j][i];
        if(sum==n) ++res;
    }
    printf("%d",res);
    return 0;
}
View Code

 好的还有nm/32的写法 但是实测没快多少

#include<cstdio>
#include<bitset>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
const int M=107;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,ans;
bitset<107>f[107];
int first[M],cnt,in[M],vis[M],map[M][M];
queue<int>q;
int main(){
    int x,y;
    n=read(); m=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),map[y][x]=1,in[x]++;
    for(int i=1;i<=n;i++){
        f[i][i]=1;
        if(!in[i]) q.push(i),vis[i]=1;
    }
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=1;i<=n;i++)if(map[x][i]&&!vis[i]){
            in[i]--;
            f[i]|=f[x];
            if(!in[i]) vis[i]=1,q.push(i);
        }
    }
    int ans=0;
     for(int i=1;i<=n;i++){
        int sum=0;
        for(int j=1;j<=n;j++) sum+=f[i][j]|f[j][i];
        if(sum==n) ans++;
    }
    printf("%d\n",ans);
    return 0;
}
View Code

bzoj1614: [Usaco2007 Jan]Telephone Lines架设电话线——二分答案

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=2e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,mx;
int first[M],cnt,d[M],vis[M];
struct node{int to,next,w;}e[10*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
queue<int>q;
int spfa(int mx){
    memset(vis,0,sizeof(d));
    memset(d,0x3f,sizeof(d));
    q.push(1); d[1]=0;
    while(!q.empty()){
        int x=q.front(); q.pop();
        vis[x]=0;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to,v=d[x]+(e[i].w>mx);
            if(d[now]>v){
                d[now]=v;
                if(!vis[now]) vis[now]=1,q.push(now);
            }
        }
    }
    return d[n]<=k;
}
int main()
{
    int x,y,w;
    n=read(); m=read(); k=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w),mx=max(mx,w);
    int ans=-1,l=0,r=mx;
    while(l<=r){
        int mid=(l+r)>>1;
        if(spfa(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj  1603. -- [Usaco2008 Oct]打谷机——简单模拟

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=1e3+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,cnt,d[M];
struct node{int x,y,c;}e[M];
bool cmp(node a,node b){return a.x<b.x;}
int main()
{
    n=read();
    for(int i=1;i<n;i++) e[i].x=read(),e[i].y=read(),e[i].c=read();
    sort(e+1,e+n,cmp);
    d[1]=0;
    for(int i=1;i<n;i++)
     if(e[i].c==0) d[e[i].y]=d[e[i].x];
     else d[e[i].y]=1-d[e[i].x];
    printf("%d\n",d[n]);
    return 0;
}
View Code

 bzoj 1599: [Usaco2008 Oct]笨重的石子

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int s[4],mx,ans;
int f[107],sum;
int main()
{
    for(int i=1;i<=3;i++) s[i]=read(),sum+=s[i];
    for(int s1=1;s1<=s[1];s1++)
     for(int s2=1;s2<=s[2];s2++)
      for(int s3=1;s3<=s[3];s3++)
       f[s1+s2+s3]++;
    for(int i=1;i<=sum;i++) if(f[i]>mx) mx=f[i],ans=i;
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1692: [Usaco2007 Dec]队列变换——后缀数组

 暂时不会写 留坑代填 填在后面了233(没用后缀数组QAQ)

bzoj 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛——简单dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=107;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,T;
int sx,sy,ex,ey;
int f[M][M][25],map[M][M];
int xi[5]={0,0,1,0,-1},yi[5]={0,1,0,-1,0};
char s[155];
int main()
{
    n=read(); m=read(); T=read();
    for(int i=1;i<=n;i++){
        scanf("%s",s+1);
        for(int j=1;j<=m;j++) if(s[j]=='.') map[i][j]=1;
    }
    sx=read(); sy=read(); ex=read(); ey=read();
    f[sx][sy][0]=1;
    for(int k=1;k<=T;k++)
     for(int x=1;x<=n;x++)
      for(int y=1;y<=m;y++)if(map[x][y])
          for(int i=1;i<=4;i++){
              int nx=x+xi[i],ny=y+yi[i];
              if(nx<1||nx>n||ny<1||ny>m||!map[nx][ny]||!f[nx][ny][k-1]) continue;
              f[x][y][k]+=f[nx][ny][k-1];
          }
    printf("%d\n",f[ex][ey][T]);
    return 0;
}
View Code

 bzoj1666 : [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏——模拟

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=107;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,ans;
int main()
{
    n=read();
    while(n!=1){
        ans++;
        if(n%2) n=n*3+1;
        else n/=2;
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路——最小生成树

1. Kruskal 这个写法超级慢QAQ 直接n^2logn^2 暴力

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int M=1e3+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,f[M],map[M][M];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
double x[M],y[M],ans;
double calc(int p,int q){return sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));}
int cnt,sum;
struct node{int from,to; double d;}e[M*M];
bool cmp(node a,node b){return (b.d-a.d)>1e-7;}
int main()
{
    int p,q;
    n=read(); m=read();
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]);
    for(int i=1;i<=m;i++){
        p=read(); q=read();
        map[p][q]=map[q][p]=1;
        e[++cnt]=(node){p,q,calc(p,q)};
    }
    sort(e+1,e+1+cnt,cmp);
    for(int i=1;i<=cnt;i++){
        int p=find(e[i].from),q=find(e[i].to);
        if(p==q) continue;
        sum++; f[q]=p;
    }
    if(sum==n) return printf("%.2lf\n",ans),0;
    cnt=0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)if(!map[i][j])
            e[++cnt]=(node){i,j,calc(i,j)};
    sort(e+1,e+1+cnt,cmp);
    for(int i=1;i<=cnt;i++){
        int p=find(e[i].from),q=find(e[i].to);
        if(p==q) continue;
        ans+=e[i].d; f[q]=p;
        sum++; if(sum==n) break;
    }printf("%.2lf\n",ans);
    return 0;
}
View Code

2. prim 快好多啊 稠密图n^2 比 kruskal 快好多啊QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int M=1e3+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,vis[M],f[M][M];
double x[M],y[M],ans,map[M][M],d[M];
double calc(int p,int q){return sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));}
void prim(){
    d[1]=0; vis[1]=1;
    for(int i=2;i<=n;i++) d[i]=map[1][i];
    for(int i=2;i<=n;i++){
        double mn=inf;
        int h=0;
        for(int j=2;j<=n;j++) if(!vis[j]&&mn>d[j]) mn=d[j],h=j;
        ans+=mn; d[h]=0; vis[h]=1;
        for(int j=2;j<=n;j++) if(!vis[j]&&map[h][j]<d[j]) d[j]=map[h][j];
    }
}
int main()
{
    int p,q;
    n=read(); m=read();
    for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]);
    for(int i=1;i<=m;i++){
        p=read(); q=read();
        f[p][q]=f[q][p]=1;
    }
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)if(!f[i][j])
            map[i][j]=map[j][i]=calc(i,j);
    prim();
    printf("%.2lf\n",ans);
    return 0;
}
View Code

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

又一个代填的坑QAQ 

这又是一道能用hash填的坑 我们可以二分答案 然后用hash套hash的方法写辣 复杂度nlongn

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL unsigned long long
const int M=45007,P=9875321,mod=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k;
LL w[M],f[M];
int first[mod],cnt,ans[M];
struct node{LL v; int next;}e[M];
int find(LL x){
    LL w=x%mod;
    for(int i=first[w];i;i=e[i].next)if(e[i].v==x) return i;
    e[++cnt]=(node){x,first[w]}; first[w]=cnt;
    return cnt;
}
bool check(int l){
    cnt=0;
    memset(first,0,sizeof(first));
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=n-l+1;i++){
        LL ly=f[i+l-1]-f[i-1]*w[l];
        int s=find(ly);
        ans[s]++;
        if(ans[s]>=k) return 1;
    }
    return 0;
}
int main(){
    n=read(); k=read();
    w[0]=1; for(int i=1;i<=n;i++) w[i]=w[i-1]*P;
    for(int i=1;i<=n;i++) f[i]=f[i-1]*P+read();
    if(k==0) return printf("%d\n",n),0;
    int l=0,r=n;
    while(l<r){
        int mid=(l+r+1)>>1;
        if(check(mid)) l=mid;
        else r=mid-1;
    }printf("%d\n",l);
    return 0;
}
View Code

【bzoj1611】[Usaco2008 Feb]Meteor Shower流星雨-bfs

小心数组越界QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=55007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f; 
}
int n,xx[5]={0,0,1,0,-1},yy[5]={0,1,0,-1,0};
int map[307][307],vis[307][307];
struct node{int x,y,T;};
queue<node>q;
int main()
{
    for(int i=0;i<=305;i++) for(int j=0;j<=305;j++) map[i][j]=inf;
    int x,y,h;
    n=read();
    for(int i=1;i<=n;i++){
        x=read(); y=read(); 
        h=read(); map[x][y]=min(map[x][y],h);
        for(int k=1;k<=4;k++){
            int nx=x+xx[k],ny=y+yy[k];
            if(nx<0||ny<0) continue;//小心数组越界 
            map[nx][ny]=min(map[nx][ny],h);
        }
    }
    if(!map[0][0]) return printf("-1\n"),0;
    vis[0][0]=1;
    q.push((node){0,0,0});
    while(!q.empty()){
        node s=q.front(); q.pop();
        if(map[s.x][s.y]==inf) return printf("%d\n",s.T),0;
        for(int k=1;k<=4;k++){
            int nx=s.x+xx[k],ny=s.y+yy[k],nowh=s.T+1;
            if(nx<0||ny<0||map[nx][ny]<=nowh||vis[nx][ny]) continue;
            vis[nx][ny]=1; 
            q.push((node){nx,ny,nowh});
        }
    }printf("-1\n");
    return 0;
}
View Code

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

切割的逆过程就是合并 所以切割木板=合并果子

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL n,k,ans;
struct node{
    LL w;
    bool operator <(const node& x)const {return x.w<w;}
};
priority_queue<node>q;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) k=read(),q.push((node){k});
    for(int i=1;i<n;i++){
        node x=q.top(); q.pop();
        node y=q.top(); q.pop();
        int h=x.w+y.w;
        ans+=h;
        q.push((node){h});
    }printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1621: [Usaco2008 Open]Roads Around The Farm分岔路口——模拟

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,ans;
queue<int>q;
int main()
{
    n=read(); k=read();
    q.push(n);
    while(!q.empty()){
        int x=q.front(); q.pop();
        if(x>k&&(x-k)%2==0){
            int now1=(x-k)/2,now2=now1+k;
            q.push(now1);
            q.push(now2);
        }
        else ans++;
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛-二分求最长上升子序列

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=5007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,d,q[M],cnt;
int find(int w){
    int l=0,r=cnt;
    while(l<=r){
        int mid=(l+r)>>1;
        if(q[mid]<w) l=mid+1;
        else r=mid-1;
    }
    return l;
}
int main()
{
    n=read(); 
    k=read(); q[++cnt]=k;
    for(int i=2;i<=n;i++){
        k=read(); 
        if(q[cnt]<k) q[++cnt]=k;
        else d=find(k),q[d]=k;
    }printf("%d\n",cnt);
    return 0;
}
View Code

 bzoj 1232: [Usaco2008Nov]安慰奶牛cheer——最小生成树 

每条边的权值就是他的两个端点的c+他的长度*2

当然要记得选一个权值最小的点当作跟

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=10007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans=inf,n,m,first[M],cnt,c[M],f[M];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
struct node{int from,to,w,next;}e[15*M];
bool cmp(node a,node b){return a.w<b.w;}
void ins(int a,int b,int w){e[++cnt]=(node){a,b,w,first[a]}; first[a]=cnt;}
int main()
{
    int x,y,w;
    n=read(); m=read();
    for(int i=1;i<=n;i++) c[i]=read(),f[i]=i,ans=min(ans,c[i]);
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(x,y,(w<<1)+c[x]+c[y]);
    sort(e+1,e+1+cnt,cmp);
    int h=0; 
    for(int i=1;i<=m;i++){
        int p=find(e[i].from),q=find(e[i].to);
        if(p==q) continue;
        f[q]=p; ans+=e[i].w; 
        h++; if(h==n-1) break;
    }printf("%d\n",ans);
}
View Code

 bzoj 1636: [Usaco2007 Jan]Balanced Lineup-zkw线段树

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1<<19,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,q,l,r;
int mx[N<<1],mn[N<<1];
int push_ans(int l,int r){
    int mx1=0,mn1=inf;
    for(l+=N-1,r+=N+1;r-l!=1;l>>=1,r>>=1){
        if(~l&1) mx1=max(mx1,mx[l^1]),mn1=min(mn1,mn[l^1]);
        if(r&1)     mx1=max(mx1,mx[r^1]),mn1=min(mn1,mn[r^1]);
    }
    return mx1-mn1;
}
int main()
{
    n=read(); q=read();
    for(int i=1;i<=n;i++) mx[N+i]=mn[N+i]=read();
    for(int i=N-1;i;i--) mx[i]=max(mx[i<<1],mx[i<<1^1]),mn[i]=min(mn[i<<1],mn[i<<1^1]);
    for(int i=1;i<=q;i++){
        l=read(); r=read();
        printf("%d\n",push_ans(l,r));
    }
    return 0;
}
View Code

 bzoj 1618: [Usaco2008 Nov]Buying Hay 购买干草——完全背包

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
} 
int n,h,mx,ans=inf;
int f[55007];
int c[107],w[107];
int main()
{
    n=read(); h=read();
    for(int i=1;i<=n;i++) c[i]=read(),w[i]=read(),mx=max(mx,c[i]);
    memset(f,0x3f,sizeof(f)); f[0]=0;
    for(int i=1;i<=n;i++)
        for(int j=c[i];j<h+mx;j++)
            f[j]=min(f[j],f[j-c[i]]+w[i]);
    for(int i=0;i<mx;i++) ans=min(ans,f[h+i]);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1572: [Usaco2009 Open]工作安排Job——贪心+堆

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=100007;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
} 
LL n,cnt,ans;
struct pos{LL d,w;}e[M];
bool cmp(pos a,pos b){return a.d<b.d;}
priority_queue<LL>q;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) e[i].d=read(),e[i].w=read();
    sort(e+1,e+1+n,cmp);
    for(int i=1;i<=n;i++){
        ans+=e[i].w; q.push(-e[i].w); cnt++;
        if(cnt>e[i].d) cnt--,ans+=q.top(),q.pop();
    }printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1631: [Usaco2007 Feb]Cow Party——spfa

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1007,M=150007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k;
int first[N],cnt,star[N],cntq;
struct node{int to,next,w;}e[M],q[M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insq(int a,int b,int w){q[++cntq]=(node){b,star[a],w}; star[a]=cnt;}
int d1[N],d2[N],vis[N];
queue<int>qu;
void spfa1(){
    memset(d1,0x3f,sizeof(d1));
    d1[k]=0; vis[k]=1; qu.push(k);
    while(!qu.empty()){
        int x=qu.front(); vis[x]=0; qu.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(d1[now]>d1[x]+e[i].w){
                d1[now]=d1[x]+e[i].w;
                if(!vis[now]) qu.push(now),vis[now]=1;
            }
        } 
    }
}
void spfa2(){
    memset(d2,0x3f,sizeof(d2));
    d2[k]=0; vis[k]=1; qu.push(k);
    while(!qu.empty()){
        int x=qu.front(); vis[x]=0; qu.pop();
        for(int i=star[x];i;i=q[i].next){
            int now=q[i].to;
            if(d2[now]>d2[x]+q[i].w){
                d2[now]=d2[x]+q[i].w;
                if(!vis[now]) qu.push(now),vis[now]=1;
            }
        } 
    }
}
int main()
{
    int x,y,w;
    n=read(); m=read(); k=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(x,y,w),insq(y,x,w);
    spfa1();
    spfa2();
    int ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,d1[i]+d2[i]);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1231: [Usaco2008 Nov]mixup2 混乱的奶牛——状压dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int s,n,mn;
LL f[20][1<<16],h[25],w[25];
int main()
{
    n=read(); mn=read(); s=(1<<n)-1;
    for(int i=1;i<=n;i++) h[i]=read(),w[i]=1<<(i-1),f[i][w[i]]=1;
    for(int k=1;k<=s;k++)
        for(int i=1;i<=n;i++)if(!(k&w[i]))
            for(int j=1;j<=n;j++)if((k&w[j])&&abs(h[i]-h[j])>mn)
                f[i][k|w[i]]+=f[j][k];
    LL ans=0;
    for(int i=1;i<=n;i++) ans+=f[i][s];
    printf("%lld\n",ans); 
    return 0;
}
View Code

 bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路——spfa求次短路

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=5007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m;
int first[M],cnt;
struct node{int to,next,w;}e[250007];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
int d1[M],d2[M],vis[M];
queue<int>q;
void spfa(){
    memset(d1,0x3f,sizeof(d1));
    memset(d2,0x3f,sizeof(d2));
    d1[1]=0; vis[1]=0; q.push(1);
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            bool f=false;
            int now=e[i].to;
            if(d1[x]+e[i].w<d1[now]) f=true,d2[now]=min(d1[now],d2[x]+e[i].w),d1[now]=d1[x]+e[i].w;
            else if(d1[x]+e[i].w>d1[now]&&d1[x]+e[i].w<d2[now]) f=true,d2[now]=d1[x]+e[i].w;
            else if(d2[x]+e[i].w<d2[now]) f=true,d2[now]=d2[x]+e[i].w;
            if(f&&!vis[now]) vis[now]=1,q.push(now);
        }
        vis[x]=0;
    }
}
int main()
{
    int x,y,w;
    n=read(); m=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    spfa();
    printf("%d\n",d2[n]);
    return 0;
}
View Code

 bzoj 1677: [Usaco2005 Jan]Sumsets 求和——完全背包

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=1e9,M=1e6+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,f[M];
int main()
{
    n=read();
    f[0]=1;
    for(int i=0;(1<<i)<=n;i++){
        int now=1<<i;
        for(int j=now;j<=n;j++) (f[j]+=f[j-now])%=mod;
    }printf("%d\n",f[n]);
    return 0;
}
View Code

 bzoj 1657: [Usaco2006 Mar]Mooo 奶牛的歌声——单调栈

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=50007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,h[M],v[M];
int st[M],top,s[M],ans;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) h[i]=read(),v[i]=read();
    for(int i=1;i<=n;i++){
        while(top&&h[st[top]]<h[i]) s[i]+=v[st[top--]];
        st[++top]=i;
    }
    top=0;
    for(int i=n;i;i--){
        while(top&&h[st[top]]<h[i]) s[i]+=v[st[top--]];
        st[++top]=i;
    }
    for(int i=1;i<=n;i++) ans=max(ans,s[i]);
    printf("%d\n",ans);
    return 0;
}
View Code

bzoj 1646: [Usaco2007 Open]Catch That Cow 抓住那只牛——bfs

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int mx=100000;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int s,k,now,d[mx+7];
queue<int>q;
int main()
{
    s=read(); k=read();
    q.push(s); d[s]=1;
    if(s>=k) return printf("%d\n",s-k),0;
    while(!q.empty()){
        int x=q.front(); q.pop();
        now=x+1;if(now>=0&&now<=mx&&!d[now]) d[now]=d[x]+1,q.push(now);
        now=x-1;if(now>=0&&now<=mx&&!d[now]) d[now]=d[x]+1,q.push(now);
        now=2*x;if(now>=0&&now<=mx&&!d[now]) d[now]=d[x]+1,q.push(now);
        if(d[k]) return printf("%d\n",d[k]-1),0;
    }
    return 0;
}
View Code

 bzoj 1660: [Usaco2006 Nov]Bad Hair Day 乱发节——单调栈

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int h[M],n;
LL ans;
int st[M],top;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) h[i]=read();
    for(int i=1;i<=n;i++){
        while(top&&h[st[top]]<=h[i]) top--;
        ans+=top; st[++top]=i;
    }printf("%lld\n",ans);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,x[M];
int check(int k){
    int sum=x[1],cnt=1;
    for(int i=2;i<=n;i++)if(x[i]-sum>=k) cnt++,sum=x[i];
    return cnt>=m;
}
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) x[i]=read();
    sort(x+1,x+1+n);
    int l=0,r=x[n];
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) l=mid+1;
        else r=mid-1;
    }printf("%d\n",r);
    return 0;
}
View Code

 bzoj 1679: [Usaco2005 Jan]Moo Volume 牛的呼声——排序

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=1e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,x[M];
LL ans;
int main()
{
    n=read(); 
    for(int i=1;i<=n;i++) x[i]=read();
    sort(x+1,x+1+n);
    LL sum=x[1];
    for(int i=2;i<=n;i++) ans=ans+1LL*(i-1)*x[i]-sum,sum+=x[i];
    printf("%lld\n",ans*2);
    return 0;
}
View Code

 bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+Dijkstra

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int N=10007,inf=0x7f7f7f7f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k;
int d[N][25];
struct node{
    int d,h,pos;
    bool operator <(const node& x)const{return x.d<d;}
};
priority_queue<node>q;
int first[N],cnt;
struct pos{int to,next,w;}e[10*N];
void ins(int a,int b,int w){e[++cnt]=(pos){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
int dj(){
    memset(d,0x7f,sizeof(d));
    for(int i=0;i<=k;i++) d[1][i]=0; 
    q.push((node){0,0,1});
    while(!q.empty()){
        node p=q.top(); q.pop();
        if(d[p.pos][p.h]!=p.d) continue;
        if(p.pos==n) return p.d;
        int x=p.pos,h=p.h;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(d[now][h]>d[x][h]+e[i].w) d[now][h]=d[x][h]+e[i].w,q.push((node){d[now][h],h,now});
            if(h<k&&d[now][h+1]>d[x][h]) d[now][h+1]=d[x][h],q.push((node){d[now][h+1],h+1,now});
        }
    }
    return d[n][k];
}
int main()
{
    int x,y,v;
    n=read(); m=read(); k=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),v=read(),insert(x,y,v);
    printf("%d\n",dj());
    return 0;
}
View Code

 bzoj 1711: [Usaco2007 Open]Dining吃饭——网络流

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=1e3+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k;
int S,T,N,ans;
int first[M],cur[M],cnt=1;
struct node{int to,next,flow;}e[M*M];
void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
int d[M];
queue<int>q;
int bfs(){
    memset(d,-1,sizeof(d));
    d[S]=1; q.push(S);
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now);
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||a==0) return a;
    int flow=0,f;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,min(e[i].flow,a)))>0){
            e[i].flow-=f; e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int main()
{
    int x,y,v;
    n=read(); m=read(); k=read();
    S=0; T=n*2+m+k+1; N=n*2;
    for(int i=1;i<=n;i++) insert(i,i+n,1);
    for(int i=1;i<=m;i++) insert(S,i+N,1);
    for(int i=1;i<=k;i++) insert(i+N+m,T,1);
    for(int i=1;i<=n;i++){
        x=read(); y=read();
        for(int j=1;j<=x;j++) v=read(),insert(v+N,i,1);
        for(int j=1;j<=y;j++) v=read(),insert(i+n,v+N+m,1);
    }
    while(bfs()){
        for(int i=S;i<=T;i++) cur[i]=first[i];
        ans+=dfs(S,inf);
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚——差分

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e6+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,s[M],l,r,mx;
int main()
{
    n=read();
    for(int i=1;i<=n;i++){
        l=read(); r=read();
        mx=max(mx,r);
        s[l]++; s[r+1]--;
    }
    int sum=0,ans=0;
    for(int i=1;i<=mx;i++) sum+=s[i],ans=max(ans,sum);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1690: [Usaco2007 Dec]奶牛的旅行——分数规划+spfa判负环

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e3+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
bool f;
int n,m,v[M];
int first[M],cnt;
struct node{int to,next,w; double h;}e[10*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w,0}; first[a]=cnt;}
int vis[M];
double d[M];
void dfs(int x){
    vis[x]=1;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]>d[x]+e[i].h){
            if(vis[now]){f=true; return ;}
            d[now]=d[x]+e[i].h;
            dfs(now);
        }
    }
    vis[x]=0;
}
bool check(double k){
    for(int i=1;i<=cnt;i++) e[i].h=k*e[i].w-v[e[i].to];
    for(int i=1;i<=n;i++) d[i]=vis[i]=0;
    f=false; 
    for(int i=1;i<=n;i++){dfs(i); if(f) return 1;}
    return 0;
}
int main()
{
    int x,y,w;
    n=read(); m=read();
    for(int i=1;i<=n;i++) v[i]=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(x,y,w);
    double l=0.0,r=10000;
    while(r-l>1e-3){
        double mid=(l+r)/2;
        if(check(mid)) l=mid;
        else r=mid;
    }printf("%.2f\n",l);
    return 0;
}
View Code

bzoj 1708: [Usaco2007 Oct]Money奶牛的硬币——完全背包

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,c[55];
LL f[10007];
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) c[i]=read();
    f[0]=1;
    for(int i=1;i<=n;i++)
        for(int j=c[i];j<=m;j++)
            f[j]+=f[j-c[i]];
    printf("%lld\n",f[m]);
    return 0;
}
View Code

 bzoj 1634: [Usaco2007 Jan]Protecting the Flowers 护花——贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n;
struct node{
    int T,d;
    bool operator <(const node& x)const{return T*x.d<x.T*d;}
}e[M];
LL ans,sum;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) e[i].T=read(),e[i].d=read(),sum+=e[i].d;
    sort(e+1,e+1+n);
    for(int i=1;i<=n;i++){
        sum-=e[i].d;
        ans+=2*e[i].T*sum;
    }printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1629: [Usaco2007 Demo]Cow Acrobats——贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,ans,sum;
struct node{int w,s;}e[M];
bool cmp(node a,node b){return b.s-a.w>a.s-b.w;}
int main()
{
    n=read();
    for(int i=1;i<=n;i++) e[i].w=read(),e[i].s=read();
    sort(e+1,e+1+n,cmp); 
    ans=-e[1].s; sum=e[1].w;
    for(int i=2;i<=n;i++){
        ans=max(ans,sum-e[i].s);
        sum+=e[i].w;
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1725: [Usaco2006 Nov]Corn Fields牧场的安排——状压dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=1e9;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,cnt,ans;
int s[15],f[15][20007];
bool pd(int x){return (x&(x<<1))==0;}
int main()
{
    n=read(); m=read(); cnt=(1<<m)-1;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[i]=(s[i]<<1)+(read()^1);
    for(int i=0;i<=cnt;i++) if(pd(i)&&!(i&s[1])) f[1][i]=1;
    for(int i=2;i<=n;i++)
        for(int j=0;j<=cnt;j++) if(!(j&s[i])&&pd(j))
        for(int k=0;k<=cnt;k++) if(!(j&k)&&!(k&s[i-1])&&pd(k))
        (f[i][j]+=f[i-1][k])%=mod;
    for(int i=0;i<=cnt;i++) (ans+=f[n][i])%=mod;
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1620: [Usaco2008 Nov]Time Management 时间管理——贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=1e3+7,mod=1e9;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,ans=1e6+7;
struct node{int T,s;}e[M];
bool cmp(node a,node b){return a.s>b.s;}
int main()
{
    n=read();
    for(int i=1;i<=n;i++) e[i].T=read(),e[i].s=read();
    sort(e+1,e+1+n,cmp);
    for(int i=1;i<=n;i++) ans=min(ans,e[i].s)-e[i].T;
    if(ans<0) printf("-1\n");
    else printf("%d\n",ans);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=1e6+7;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL n,c[M];
LL sz[M],ans,dis[M];
int first[M],cnt;
struct node{int to,next; LL w;}e[2*M];
void ins(int a,int b,LL w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,LL w){ins(a,b,w); ins(b,a,w);}
LL dfs(int x,int fa){
    LL sum=dis[x]*c[x];
    sz[x]=c[x];
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to; if(now==fa) continue;
        dis[now]=dis[x]+e[i].w;
        sum+=dfs(now,x);
        sz[x]+=sz[now];
    }
    return sum;
}
void mov(int x,int fa){
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to; if(now==fa) continue;
        if(sz[1]-2*sz[now]<0){
            ans+=e[i].w*(sz[1]-2*sz[now]);
            mov(now,x); return ;
        }
    }
}
int main()
{
    LL x,y,w;
    n=read();
    for(int i=1;i<=n;i++) c[i]=read();
    for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    ans=dfs(1,-1);
    mov(1,-1);
    printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1639: [Usaco2007 Mar]Monthly Expense 月度开支——二分

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,ans,l,r;
int w[M];
int check(int k){
    int sum=0,cnt=1;
    for(int i=1;i<=n;i++)
        if(sum+w[i]<=k) sum+=w[i];
        else{
            sum=w[i]; cnt++;
            if(cnt>m||w[i]>k) return 0;
        }
    return 1;
}
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) w[i]=read(),r+=w[i];
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }printf("%d\n",ans);
    return 0;
}
View Code

 临时改变计划 silver刷不下去了QAQ 现在先刷gold

bzoj2442: [Usaco2011 Open]修剪草坪——单调队列优化dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=100007;
const LL inf=1e15;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k;
int head,tail,q[M];
LL ans,f[M],h[M],mn=inf;
int main()
{
    n=read(); k=read();
    for(int i=1;i<=n;i++) h[i]=read(),ans+=h[i];
    for(int i=1;i<=n;i++){
        f[i]=f[q[head]]+h[i];
        while(head<=tail&&f[q[tail]]>f[i]) tail--;
        q[++tail]=i;
        while(head<=tail&&i-q[head]>k) head++;
    }
    for(int i=n-k;i<=n;i++) mn=min(mn,f[i]);
    printf("%lld\n",ans-mn);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=2007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,s[M],h[M],f[M],ff[M];
int main()
{
    n=read(); for(int i=1;i<=n;i++) s[i]=read(),h[i]=s[i];
    sort(h+1,h+1+n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            f[j]+=abs(s[i]-h[j]);
            if(j>1) f[j]=min(f[j],f[j-1]);
        }
        for(int j=n;j;j--){
            ff[j]+=abs(s[i]-h[j]);
            if(j<n) ff[j]=min(ff[j],ff[j+1]);
        }
    }
    printf("%d\n",min(f[n],ff[1]));
    return 0;
}
View Code

 bzoj 1576: [Usaco2009 Jan]安全路经Travel——dijkstra+并查集

题解我博客有另写 请搜索bzoj 1576(记得加空格) 另外spfa会被卡

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e5+7,M=4e5+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,ans[N];
int f[N],fa[N];
int find(int x){while(x!=f[x]) x=f[x]=f[f[x]]; return x;}
int first[N],cnt,cntq;
struct node{int from,to,next,w;}e[M],qs[M];
bool cmp(node a,node b){return a.w<b.w;}
void ins(int a,int b,int w){e[++cnt]=(node){a,b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
int dis[N],dep[N];
struct Q{
    int d,pos;
    bool operator <(const Q& x)const{return x.d<d;}
};
priority_queue<Q>q;
void dj(){
    memset(dis,0x3f,sizeof(dis));
    q.push((Q){0,1}); dis[1]=0;
    while(!q.empty()){
        Q p=q.top(); q.pop();
        if(p.d>dis[p.pos]) continue;
        int x=p.pos;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(dis[now]>dis[x]+e[i].w){
                dis[now]=dis[x]+e[i].w;
                dep[now]=dep[x]+1;
                fa[now]=x;
                q.push((Q){dis[now],now});
            }
        }
    }
    //for(int i=1;i<=n;i++) printf("[%d] ",dis[i]); printf("\n");
}
int main(){
    int x,y,w;
    n=read(); m=read();
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    dj();
    for(int i=1;i<=cnt;i++){
        x=e[i].from; y=e[i].to;
        if(dep[x]<dep[y]) swap(x,y);
        if(dis[x]==dis[y]+e[i].w) continue;
        qs[++cntq]=(node){x,y,0,dis[x]+dis[y]+e[i].w};
    }
    sort(qs+1,qs+1+cntq,cmp);
    for(int i=1;i<=cntq;i++){
        x=qs[i].from; y=qs[i].to;
        while(x!=y){
            if(dep[x]<dep[y]) swap(x,y);
            if(!ans[x]) ans[x]=qs[i].w-dis[x];
            x=f[x]=find(fa[x]); //printf("[%d]\n",x);
        }
    }    
    for(int i=2;i<=n;i++){
        if(!ans[i]) printf("-1\n");
        else printf("%d\n",ans[i]);
    }
    return 0;
}
View Code

bzoj 1782: [Usaco2010 Feb]slowdown 慢慢游——dfs序

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=2e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,sum,l[M],r[M],pos[M],k;
int first[M],cnt;
struct node{int to,next;}e[2*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
void dfs(int x,int fa){
    pos[x]=l[x]=++sum;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now==fa) continue;
        dfs(now,x);
    }
    r[x]=sum;
}
int s[M];
int lowbit(int x){return x&-x;}
int query(int x){
    int ans=0;
    while(x){ans+=s[x]; x-=lowbit(x);}
    return ans;
}
void add(int x,int v){
    while(x<=n){
        s[x]+=v;
        x+=lowbit(x);
    }
}
int main(){
    int x,y;
    n=read();
    for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y);
    dfs(1,0);
    for(int i=1;i<=n;i++){
        k=read();
        int lx=l[k],rx=r[k];
        printf("%d\n",query(pos[k]));
        add(lx,1); add(rx+1,-1);
    }
    return 0;
}
View Code

bzoj 1596: [Usaco2008 Jan]电话网络——贪心+dfs

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=2e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans,n,mark[M];
int first[M],cnt;
struct node{int to,next;}e[2*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
void dfs(int x,int fa){
    bool f=false;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now==fa) continue;
        dfs(now,x);
        if(mark[now]) f=1;
    }
    if(!f&&!mark[x]&&!mark[fa]){ans++; mark[fa]=1;}
}
int main(){
    int x,y;
    n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y);
    dfs(1,0);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1692: [Usaco2007 Dec]队列变换——二分+hash

强行hash代替后缀数组QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=35007,P=9875321;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,cnt;
char s[M],ans[M];
unsigned long long h1[M],h2[M],w[M];
int find(int x,int y){
    if(s[x]!=s[y]) return 0;
    int l=1,r=y-x+1;
    while(l<r){
        int mid=(l+r)>>1;
        if(h1[x+mid]-h1[x-1]*w[mid+1]==h2[y-mid]-h2[y+1]*w[mid+1]) l=mid+1;
        else r=mid;
    }//printf("%d %d [%d]\n",x,y,l);
    return l;
}
void prepare(){
    w[0]=1;
    for(int i=1;i<=n;i++) w[i]=w[i-1]*P;
}
int main(){
    n=read(); prepare();
    for(int i=1;i<=n;i++) scanf("%s",s+i);
    for(int i=1;i<=n;i++) h1[i]=h1[i-1]*P+s[i];
    for(int i=n;i;i--) h2[i]=h2[i+1]*P+s[i];
    int l=1,r=n;
    while(l<=r){
        int d=find(l,r);
        if(s[l+d]<s[r-d]) ans[++cnt]=s[l],l++;
        else ans[++cnt]=s[r],r--;
    }//printf("[%d]\n",cnt);
    for(int i=1;i<=cnt;++i){
        putchar(ans[i]);
        if(i%80==0)putchar(10);
    }
    return 0;
}
View Code

 bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞——spfa判负环

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=507;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int T,n,m,k,vis[M],d[M];
int first[M],cnt;
struct node{int to,next,w;}e[10007];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
bool f;
void dfs(int x){
    vis[x]=1;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]>d[x]+e[i].w){
            if(vis[now]){f=true; return ;}
            d[now]=d[x]+e[i].w;
            dfs(now);
        }
    }
    vis[x]=0;
}
int pd(){
    f=false;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        memset(d,0,sizeof(d));
        dfs(i); 
        if(f) return 1;
    }
    return 0;
}
int main(){
    T=read();
    while(T--){
        int x,y,w;
        cnt=0; memset(first,0,sizeof(first));
        n=read(); m=read(); k=read();
        for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w);
        for(int i=1;i<=k;i++) x=read(),y=read(),w=read(),ins(x,y,-w);
        if(pd()) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
View Code

 bzoj 1596: [Usaco2008 Jan]电话网络——贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=2e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans,n,mark[M];
int first[M],cnt;
struct node{int to,next;}e[2*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
void dfs(int x,int fa){
    bool f=false;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now==fa) continue;
        dfs(now,x);
        if(mark[now]) f=1;
    }
    if(!f&&!mark[x]&&!mark[fa]){ans++; mark[fa]=1;}
}
int main(){
    int x,y;
    n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y);
    dfs(1,0);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1571: [Usaco2009 Open]滑雪课Ski——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=15007,N=107;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int T,n,m,ans;
int s[M],d[M],h[M],mn[N];
int c[M],w[M];
int f[M][N],k[M][N],g[M][N];
int main(){
    T=read(); n=read(); m=read();
    for(int i=1;i<=n;i++) s[i]=read(),d[i]=read(),h[i]=read(),k[s[i]+d[i]][h[i]]=s[i];
    for(int i=1;i<=m;i++) c[i]=read(),w[i]=read();
    memset(mn,0x3f,sizeof(mn));
    memset(f,-0x3f,sizeof(f));
    memset(g,-0x3f,sizeof(g));
    for(int i=1;i<=100;i++)
     for(int j=1;j<=m;j++)if(c[j]<=i) mn[i]=min(mn[i],w[j]);
    f[0][1]=g[0][1]=0;
    for(int i=1;i<=T;i++){
        for(int j=0;j<=100;j++){
            f[i][j]=f[i-1][j];
            if(i>=mn[j]) f[i][j]=max(f[i][j],f[i-mn[j]][j]+1);
            f[i][j]=max(f[i][j],g[k[i][j]][j]);
            g[i][j]=max(g[i][j-1],f[i][j]);
        }
    }
    for(int i=1;i<=100;i++) ans=max(ans,f[T][i]);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1770: [Usaco2009 Nov]lights 燈

1.折半搜索

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=9875321,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans[1<<19],n,m,h,mn=inf;
LL p[55],tot;
bool f;
int first[mod],cnt;
struct node{LL v; int next;}e[1<<19];
int get(LL w){
    int x=w%mod;
    for(int i=first[x];i;i=e[i].next) if(e[i].v==w) return i;
    e[++cnt]=(node){w,first[x]}; first[x]=cnt; 
    return cnt;
}
void dfs(int x,LL now,int step){
    if(x==h+1){
        int k;
        if(now==tot) mn=min(mn,step);
        if(!f){
            k=get(now);
            if(!ans[k]||ans[k]>step) ans[k]=step;
        }
        else{
            k=get(tot-now);
            if(!ans[k]) return ;
            mn=min(mn,ans[k]+step);
        }
        return ;
    }
    dfs(x+1,now,step);
    dfs(x+1,now^p[x],step+1);
}
int main(){
    int x,y;
    n=read(); m=read(); tot=(1LL<<n)-1;
    for(int i=1;i<=n;i++) p[i]=1LL<<(i-1);
    for(int i=1;i<=m;i++){
        x=read(); y=read();
        p[x]^=1LL<<(y-1); p[y]^=1LL<<(x-1);
    }
    f=false; h=n/2; dfs(1,0,0); 
    f=true;  h=n; dfs(n/2+1,0,0);
    printf("%d\n",mn);
    return 0;
}
View Code

 2.高斯消元——待填

bzoj  1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富——dp(最长路)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=107,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,now;
int s[N][N],d[N][N];
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[i][j]=read();
    memset(d,-0x3f,sizeof(d)); d[1][1]=s[1][1];
    for(int i=2;i<=m;i++)
        for(int j=1;j<=n;j++){
            now=j-1;if(now>=1&&now<=n) d[j][i]=max(d[j][i],d[now][i-1]+s[j][i]); 
            now=j;  if(now>=1&&now<=n) d[j][i]=max(d[j][i],d[now][i-1]+s[j][i]);
            now=j+1;if(now>=1&&now<=n) d[j][i]=max(d[j][i],d[now][i-1]+s[j][i]);
        }
    printf("%d\n",d[n][m]);
    return 0;
}
View Code

 bzoj 1691: [Usaco2007 Dec]挑剔的美食家——贪心+平衡树

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define LL long long
const int M=150007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m;
LL ans;
struct node{
    int w,c;
    bool operator <(const node& x)const{return x.c<c;}
}e[M],q[M];
std::multiset<int>tr;
std::multiset<int>::iterator it;
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++) e[i].w=read(),e[i].c=read();
    for(int i=1;i<=m;i++) q[i].w=read(),q[i].c=read();
    std::sort(e+1,e+1+n); 
    std::sort(q+1,q+1+m);
    int k=1;
    for(int i=1;i<=n;i++){
        while(k<=m&&q[k].c>=e[i].c) tr.insert(q[k++].w);
        it=tr.lower_bound(e[i].w);
        if(it!=tr.end()) ans+=*it,tr.erase(it);
        else return puts("-1"),0;
    }printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1593: [Usaco2008 Feb]Hotel 旅馆——线段树

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1<<17;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int k,d,n,m,L,R;
struct node{int l,r,lr,rl,mx,h[2];}tr[M];
void up(int x){
    int l=x<<1,r=x<<1^1;
    tr[x].lr=tr[l].lr;    
    if(tr[l].lr==tr[l].r-tr[l].l+1) tr[x].lr=tr[l].lr+tr[r].lr;
    tr[x].rl=tr[r].rl;
    if(tr[r].rl==tr[r].r-tr[r].l+1) tr[x].rl=tr[r].rl+tr[l].rl;
    tr[x].mx=max(max(tr[l].mx,tr[r].mx),tr[l].rl+tr[r].lr);
}
void calc(int x){
    tr[x].lr=tr[x].rl=tr[x].mx=0;
    tr[x].h[0]=1; tr[x].h[1]=0;
}
void calc1(int x){
    tr[x].lr=tr[x].rl=tr[x].mx=tr[x].r-tr[x].l+1;
    tr[x].h[1]=1; tr[x].h[0]=0;
}
void down(int x){
    int l=x<<1,r=x<<1^1;
    if(tr[x].h[0]){        
        calc(l); calc(r);
        tr[x].h[0]=0;
    }
    if(tr[x].h[1]){
        calc1(l); calc1(r);
        tr[x].h[1]=0;
    }
}
void build(int x,int l,int r){
    tr[x].l=l; tr[x].r=r;
    if(l==r){
        tr[x].lr=tr[x].rl=tr[x].mx=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1^1,mid+1,r);
    up(x);
}
void modify(int x,int s){
    if(L<=tr[x].l&&tr[x].r<=R){
        if(s==0) calc(x);
        else calc1(x);
        return ;
    }
    down(x);
    int mid=(tr[x].l+tr[x].r)>>1;
    if(L<=mid) modify(x<<1,s);
    if(R>mid) modify(x<<1^1,s);
    up(x);
}
int find(int x,int d){
    down(x); 
    int l=x<<1,r=x<<1^1,mid=(tr[x].l+tr[x].r)>>1;
    if(tr[x].l==tr[x].r) return l;
    if(tr[l].mx>=d) return find(l,d);
    if(tr[l].rl+tr[r].lr>=d) return mid-tr[l].rl+1;
    return find(r,d);
}
int main(){
    n=read(); m=read();
    build(1,1,n);
    for(int i=1;i<=m;i++){
        k=read();
        if(k==1){
            d=read();
            if(tr[1].mx<d) printf("0\n");
            else{
                int y=find(1,d);
                printf("%d\n",y);
                L=y; R=y+d-1;
                modify(1,0);
            }
        }
        else{
            L=read(); R=L+read()-1;
            modify(1,1);
        }
    }
    return 0;
}
View Code

 bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居——排序+贪心+set

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
const int M=150007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,c;
int f[M],h[M],ans,mx;
int find(int x){while(f[x]!=x) x=f[x]=f[f[x]]; return x;}
struct node{
    int x,y,id;
    bool operator <(const node& k)const{return x<k.x;}
}e[M];
struct pos{
    int y,id;
    bool operator <(const pos& k)const{return y!=k.y?y<k.y:id<k.id;}
};
std::queue<int>q;
std::multiset<pos>tr;
std::multiset<pos>::iterator it;
int main(){
    int x,y;
    n=read(); c=read();
    for(int i=1;i<=n;i++){
        x=read(); y=read();
        f[i]=i; e[i].x=x+y,e[i].y=x-y; e[i].id=i;
    }
    sort(e+1,e+1+n);
    for(int i=1;i<=n;i++){
        while(!q.empty()&&e[i].x-e[q.front()].x>c){
            int now=q.front(); q.pop();
            tr.erase(tr.find((pos){e[now].y,e[now].id}));
        }
        q.push(i);
        it=tr.insert((pos){e[i].y,e[i].id});
        if(it!=tr.begin()){
            --it;
            if(e[i].y-(it->y)<=c){
                int p=find(e[i].id),q=find(it->id);
                f[q]=p;
            }
            ++it;
        }
        ++it;
        if(it!=tr.end()){
            if(it->y-e[i].y<=c){
                int p=find(e[i].id),q=find(it->id);
                f[q]=p;
            }
        }
    }
    for(int i=1;i<=n;i++){
        int x=find(e[i].id);
        if(!h[x]) ans++;
        h[x]++; mx=max(mx,h[x]);
    }printf("%d %d\n",ans,mx);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=10007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,v[M],s[M],vis[M],ans;
void mins(int &x,int y){if(y<x) x=y;}
int min(int x,int y){return x<y?x:y;}
int main(){
    n=read();
    for(int i=1;i<=n;i++) v[i]=s[i]=read();
    sort(s+1,s+1+n);
    for(int i=1;i<=n;i++)if(!vis[i]){
        int mn=v[i],sum=v[i],now=i,h=1;
        while(1){
            vis[now=lower_bound(s+1,s+1+n,v[now])-s]=1;
            if(now==i) break;
            h++; mins(mn,v[now]);
            sum+=v[now];
        }
        ans=ans+min((sum-mn)+(h-1)*mn,(s[1]+mn)*2+(sum-mn)+(h-1)*s[1]);
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果——拓扑排序求基环树

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=150007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,to[M],in[M],stk[M],top,f[M];
int head,tail,q[M];
int main(){
    n=read();
    for(int i=1;i<=n;i++) to[i]=read(),in[to[i]]++;
    for(int i=1;i<=n;i++) if(!in[i]) q[tail++]=i;
    while(head<=tail){
        int x=q[head++],now=to[x];
        in[now]--;
        if(!in[now]) q[tail++]=now;
    }
    for(int i=1;i<=n;i++)if(in[i]){
        int now=i,h=1;
        stk[top=1]=i; in[i]=0;
        while(1){
            now=to[now];
            if(now==i) break;
            h++; in[now]=0; stk[++top]=now;
        }
        while(top) f[stk[top]]=h,top--;
    }
    while(tail>0) tail--,f[q[tail]]=f[to[q[tail]]]+1;
    for(int i=1;i<=n;i++) printf("%d\n",f[i]);
    return 0;
}
View Code

 bzoj 1574: [Usaco2009 Jan]地震损坏Damage——贪心+搜索

因为你一个点附近的点如果能够使其他点到达1那他也一定可以然这个点到达1 

所以把走不到1的点全部删掉然后dfs一次就行了

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=35007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,ans;
int first[M],cnt,mark[M],vis[M];
struct node{int to,next;}e[10*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
void delet(int x){for(int i=first[x];i;i=e[i].next) mark[e[i].to]=1;}
void dfs(int x){
    vis[x]=1; ans--;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!mark[now]&&!vis[now]) dfs(now);
    }
}
int main(){
    int x,y;
    n=read(); m=read(); k=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),insert(x,y);
    for(int i=1;i<=k;i++) x=read(),delet(x);
    ans=n; dfs(1); 
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1707: [Usaco2007 Nov]tanning分配防晒霜——排序贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
const int M=2507;
char buf[M*44],*ptr=buf-1;
int read(){
    int ans=0,f=1,c=*++ptr;
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=*++ptr;}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=*++ptr;}
    return ans*f;
}
int n,m,ans;
struct node{
    int l,r;
    bool operator <(const node& x)const{return r<x.r;}
}e[M];
struct pos{
    int w,h;
    bool operator <(const pos& x)const{return w<x.w;}
}q[M];
struct Q{ 
    int w,id;
    bool operator <(const Q& x)const{return w!=x.w?w<x.w:id<x.id;}
};
std::multiset<Q>tr;
std::multiset<Q>::iterator it;
int main(){
    fread(buf,1,sizeof(buf),stdin);
    n=read(); m=read();
    for(int i=1;i<=n;i++) e[i].l=read(),e[i].r=read();
    std::sort(e+1,e+1+n);
    for(int i=1;i<=m;i++) q[i].w=read(),q[i].h=read();
    std::sort(q+1,q+1+m);
    int k=1;
    for(int i=1;i<=n;i++){
        while(k<=m&&q[k].w<=e[i].r) tr.insert((Q){q[k].w,k}),k++;
        it=tr.lower_bound((Q){e[i].l,-1});
        if(it!=tr.end()){
            ans++; q[it->id].h--;
            if(!q[it->id].h) tr.erase(it);
        }
    }printf("%d\n",ans);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=157;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,s[9][M][M],f[M][M],ans;
int main(){
    int x,y;
    n=read(); k=read();
    for(int i=1;i<=k;i++){
        x=read(); y=read(); f[x][y]++;
        for(int k=1;k<=8;k++) s[k][x][y]++;
    }
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=n;j++){
            s[1][i][j]+=s[1][i][j-1];
            s[2][i][j]+=s[2][i-1][j-1];
            s[3][i][j]+=s[3][i-1][j];
            s[4][i][j]+=s[4][i-1][j+1];
        }
    for(int i=n;i;i--)
        for(int j=n;j;j--){
            s[5][i][j]+=s[5][i][j+1];
            s[6][i][j]+=s[6][i+1][j-1];
            s[7][i][j]+=s[7][i+1][j];
            s[8][i][j]+=s[8][i+1][j+1];
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            for(int k=1;k<=8;k++) s[0][i][j]+=s[k][i][j];
            if(f[i][j]) s[0][i][j]-=7*f[i][j];
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)if(s[0][i][j]==k) ans++;
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1828: [Usaco2010 Mar]balloc 农场分配——线段树

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=1e5+7,N=1<<18,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,ans,L,R;
struct node{int l,r;}q[M];
bool cmp(node a,node b){return a.r!=b.r?a.r<b.r:a.l>b.l;}
struct pos{int l,r,mn,tag;}tr[N];
void up(int x){tr[x].mn=std::min(tr[x<<1].mn,tr[x<<1^1].mn);}
void down(int x){
    if(tr[x].tag){
        int v=tr[x].tag; tr[x].tag=0;
        tr[x<<1].tag+=v; tr[x<<1^1].tag+=v;
        tr[x<<1].mn-=v;  tr[x<<1^1].mn-=v;
    }
}
void build(int x,int l,int r){
    tr[x].l=l; tr[x].r=r; 
    if(l==r){tr[x].mn=read();return ;}
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1^1,mid+1,r);
    up(x);
}
int pmin(int x){
    if(L<=tr[x].l&&tr[x].r<=R) return tr[x].mn;
    int mid=(tr[x].l+tr[x].r)>>1,mn=inf;
    down(x);
    if(L<=mid) mn=std::min(mn,pmin(x<<1));
    if(R>mid) mn=std::min(mn,pmin(x<<1^1));
    return mn;
}
void modify(int x){
    if(L<=tr[x].l&&tr[x].r<=R){tr[x].mn-=1; tr[x].tag++; return ;}
    int mid=(tr[x].l+tr[x].r)>>1;
    down(x);
    if(L<=mid) modify(x<<1);
    if(R>mid) modify(x<<1^1);
    up(x);
}
int main(){
    n=read(); m=read();
    build(1,1,n);
    for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read();
    std::sort(q+1,q+1+m,cmp);
    for(int i=1;i<=m;i++){
        L=q[i].l; R=q[i].r;
        if(pmin(1)>=1) ans++,modify(1);
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑——倍增floyd(裸

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=1e3+7,inf=0x3f3f3f3f,mod=29399;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,S,T;
int first[mod],cnt;
struct node{int v,next;}e[M];
int get(int w){
    int x=w%mod;
    for(int i=first[x];i;i=e[i].next) if(e[i].v==w) return i;
    e[++cnt]=(node){w,first[x]}; first[x]=cnt; return cnt;
}
void mins(int &x,int y){if(x>y) x=y;}
typedef int mat[M][M];
mat f,ans,tmp;
void floyd(mat b,mat c){
    memset(tmp,0x3f,sizeof(mat));
    for(int i=1;i<=cnt;i++)
    for(int k=1;k<=cnt;k++)
    for(int j=1;j<=cnt;j++) mins(tmp[i][j],b[i][k]+c[k][j]);
    memcpy(b,tmp,sizeof(mat));
}
int main(){
    int x,y,w;
    memset(f,0x3f,sizeof(mat));
    n=read(); m=read(); S=get(read()); T=get(read());
    for(int i=1;i<=m;i++) w=read(),x=get(read()),y=get(read()),f[x][y]=f[y][x]=std::min(f[x][y],w);
    memset(ans,0x3f,sizeof(mat));
    for(int i=1;i<=cnt;i++) ans[i][i]=0;
    for(;n;n>>=1,floyd(f,f)) if(n&1) floyd(ans,f);
    printf("%d\n",ans[S][T]);
    return 0;
}
View Code

 bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生——$nsqrt(n)$ DP

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
const int M=40007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,d;
int c[M],last[M],now[M],q[M],f[M];
void mins(int &x,int y){if(x>y) x=y;}
int main(){
    n=read(); m=read(); d=sqrt(n);
    for(int i=1;i<=m;i++) last[i]=-1;
    for(int i=1;i<=n;i++) c[i]=read(),now[i]=last[c[i]],last[c[i]]=i;
    for(int i=1;i<=n;i++){
        int k=1; while(k<=d&&q[k]>now[i]) k++; k--;
        f[i]=i; q[0]=i;
        for(int j=std::min(k,d);j;j--) q[j]=q[j-1];
        for(int j=1;j<=d;j++) mins(f[i],f[q[j]-1]+j*j);
    }printf("%d\n",f[n]);
    return 0;
}
View Code

 bzoj 1754: [Usaco2005 qua]Bull Math——高精度x高精度

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=55;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
char s1[M],s2[M];
int cnt1,cnt2,b[M],c[M],ans[2*M],cntq;
int main(){
    scanf("%s%s",s1,s2);
    cnt1=strlen(s1); cnt2=strlen(s2);
    for(int i=0;i<cnt1;++i) b[i]=s1[cnt1-i-1]-'0';
    for(int i=0;i<cnt2;++i) c[i]=s2[cnt2-i-1]-'0';
    cntq=cnt1+cnt2;
    for(int i=0;i<cnt1;--i){
        for(int j=0;j<cnt2;j++){
            ans[i+j]+=b[i]*c[j];
        }
    }
    for(int i=0;i<cntq;++i){
        ans[i+1]+=ans[i]/10;
        ans[i]%=10;
    }
    while(!ans[cntq]&&cntq) --cntq;
    for(int i=cntq;i>=0;--i) printf("%d",ans[i]);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=10007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,s[M];
int main(){
    n=read(); k=n/2;
    for(int i=0;i<n;i++) s[i]=read();
    std::nth_element(s,s+k,s+n);
    printf("%d\n",s[k]);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
const int M=3e3+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,cnt;
int f[M][35],cost[M];
char s[M],ch[15];
int main(){
    int x,y;
    n=read(); m=read();
    scanf("%s",s+1); cnt=strlen(s+1);
    for(int i=1;i<=n;i++){
        scanf("%s",ch); x=read(); y=read();
        cost[(int)ch[0]]=min(x,y);
    }
    for(int k=1;k<m;k++){
        for(int l=1;l<=m-k;l++){
            int r=l+k;
            f[l][r]=min(f[l+1][r]+cost[(int)s[l]],f[l][r-1]+cost[(int)s[r]]);
            if(s[l]==s[r]) f[l][r]=min(f[l][r],f[l+1][r-1]);
        }
    }printf("%d\n",f[1][m]);
    return 0;
}
View Code

 bzoj 1598: [Usaco2008 Mar]牛跑步——第K短路

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=2e3+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,h[M],d[M][105];
int first[M],cnt;
struct node{int to,next,w;}e[10*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void merge(int s1[M],int s2[M],int w){
    memset(h,0,sizeof(h));
    int cnt=0,l=1,r=1;
    while(cnt<k){
        if(s1[l]<s2[r]+w) h[++cnt]=s1[l++];
        else h[++cnt]=s2[r]+w,r++;
    }
    for(int i=1;i<=k;i++) s1[i]=h[i];
}
int main(){
    int x,y,w;
    n=read(); m=read(); k=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(y,x,w);
    memset(d,0x3f,sizeof(d));
    d[n][1]=0;
    for(int x=n-1;x;x--){
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            merge(d[x],d[now],e[i].w);
        }
    }
    for(int i=1;i<=k;i++) 
        if(d[1][i]==inf) printf("-1\n");
        else printf("%d\n",d[1][i]);
    return 0;
}
View Code

bzoj 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛——树形dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::max;
const int M=50007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,f[M][2];
int first[M],cnt;
struct node{int to,next;}e[2*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
void dfs(int x,int fa){
    f[x][1]=1;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now==fa) continue;
        dfs(now,x);
        f[x][0]=f[x][0]+max(f[now][0],f[now][1]);
        f[x][1]=f[x][1]+f[now][0];
    }
}
int main(){
    int x,y;
    n=read();
    for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y);
    dfs(1,-1);
    printf("%d\n",max(f[1][0],f[1][1]));
    return 0;
}
View Code

bzoj 1741: [Usaco2005 nov]Asteroids 穿越小行星群——网络流

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using std::min;
const int M=2e3+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,cur[M],d[M];
int S,T,ans;
int first[M],cnt=1;
struct node{int to,next,flow;}e[20*M];
void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
std::queue<int>q;
int bfs(){
    memset(d,-1,sizeof(d));
    d[S]=1; q.push(S);
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); 
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||a==0) return a;
    int flow=0,f;
    for(int& i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,min(e[i].flow,a)))>0){
            e[i].flow-=f; e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int main(){
    int x,y;
    n=read(); k=read();
    S=0; T=2*n+1;
    for(int i=1;i<=n;i++) insert(S,i,1);
    for(int i=1;i<=n;i++) insert(i+n,T,1);
    for(int i=1;i<=k;i++) x=read(),y=read(),insert(x,y+n,1);
    while(bfs()){for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf);}
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名——floyd传递闭包

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,x,y,ans;
std::bitset<1007> f[1007];
int main(){
    n=read(); m=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1;
    for(int k=1;k<=n;k++)
     for(int i=1;i<=n;i++)
         if(f[i][k]) f[i]|=f[k];
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)if(!f[i][j]&&!f[j][i]) ans++;
    printf("%d\n",ans);
    return 0;
}
View Code

bzoj 1578: [Usaco2009 Feb]Stock Market 股票市场——dp(完全背包

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::max;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,mx;
int f[550007],map[105][105];
int main(){
    n=read(); m=read(); k=read();
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) map[j][i]=read();
    mx=k;
    for(int i=2;i<=m;i++){
        memset(f,0,sizeof(f));
        for(int j=1;j<=n;j++)
        {
        //printf("%d %dQWQ\n",map[i-1][j],mx);
        for(int k=map[i-1][j];k<=mx;k++)
        f[k]=max(f[k],f[k-map[i-1][j]]+(map[i][j]-map[i-1][j]));
        }
        mx+=f[mx];
        //printf("QAQ%d\n",mx);
    }
    printf("%d\n",mx);
    return 0;
}
View Code

 bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名——floyd传递闭包

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,x,y,ans;
std::bitset<1007> f[1007];
int main(){
    n=read(); m=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1;
    for(int k=1;k<=n;k++)
     for(int i=1;i<=n;i++)
         if(f[i][k]) f[i]|=f[k];
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)if(!f[i][j]&&!f[j][i]) ans++;
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害——最小割

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=25007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int first[M],cur[M],cnt=1,ans;
int n,m,h,S,T,mark[M];
struct node{int to,next,flow;}e[10*M];
void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
std::queue<int>q;
int d[M];
int bfs(){
    memset(d,-1,sizeof(d));
    d[S]=0; q.push(S);
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(d[now]==-1&&e[i].flow) d[now]=d[x]+1,q.push(now);
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||a==0) return a;
    int flow=0,f;
    for(int& i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,std::min(e[i].flow,a)))>0){
            e[i].flow-=f; e[i^1].flow+=f;
            flow+=f; 
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int main(){
    int x,y;
    n=read(); m=read(); h=read();
    S=0; T=2*n+1;
    insert(S,1,inf); insert(1,1+n,inf);
    for(int i=1;i<=m;i++){
        x=read(); y=read();
        if(x==y) continue;
        insert(x+n,y,inf); insert(y+n,x,inf);
    }
    for(int i=1;i<=h;i++){
        x=read(); mark[x]=1;
        insert(x,x+n,inf);
        insert(x+n,T,inf);
    }
    for(int i=2;i<=n;i++) if(!mark[i]) insert(i,i+n,1);
    while(bfs()){for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf);}
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1704: [Usaco2007 Mar]Face The Right Way 自动转身机——O(n)枚举O(n)计算就可以了

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=1e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,f[M],s[M],ansm,ansk=1;
char ch[5];
bool flag;
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        scanf("%s",ch);
        if(ch[0]=='B') s[i]=1,ansm++;
    }
    for(int k=1;k<=n;k++){
        flag=false;
        int sum=0,now=0;
        for(int i=1;i<=n-k+1;i++){
            if(f[i]==k) now^=1;
            if(s[i]^now) sum++,now^=1,f[i+k]=k;    
        }
        for(int i=n-k+2;i<=n;i++){
            if(f[i]==k) now^=1;
            if(s[i]^now){flag=true; break;}
        }
        if(flag) continue;
        if(sum<ansm) ansm=sum,ansk=k;
    }
    printf("%d %d\n",ansk,ansm);
    return 0;
}
View Code

 bzoj 2199: [Usaco2011 Jan]奶牛议会——2—SAT

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
const int M=1e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int qread(){
    int x=read(),c=getchar();
    while(c!='Y'&&c!='N') c=getchar();
    if(c=='Y') return x<<1^1;
    return x<<1;
}
int n,m;
int first[M],cnt,star[M],sum;
struct node{int from,to,next;}e[2*M],q[2*M];
void ins(int a,int b){e[++cnt]=(node){a,b,first[a]}; first[a]=cnt;}
void qins(int a,int b){q[++sum]=(node){a,b,star[a]}; star[a]=sum;}
int qc,color[M],dfn[M],low[M],stk[M],last[M],top,tot;
void tarjan(int x){
    dfn[x]=low[x]=++tot;
    stk[++top]=x; last[x]=top; 
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!dfn[now]) tarjan(now),low[x]=min(low[x],low[now]);
        else if(!color[now]) low[x]=min(low[x],dfn[now]);
    }
    if(low[x]==dfn[x]){
        qc++;
        while(top>=last[x]) color[stk[top]]=qc,top--;
    }
}
int h,vis[M];
void dfs(int x){
    vis[x]=h;
    for(int i=star[x];i;i=q[i].next){
        int now=q[i].to;
        if(vis[now]!=h) dfs(now);
    }
}
int pd(int x){
    h++; dfs(x);
    for(int i=1;i<=n;i++)if(vis[color[i<<1]]==h&&vis[color[i<<1^1]]==h) return 0;
    return 1;
}
char ans[M];
int main(){
    int x,y;
    n=read(); m=read();
    for(int i=1;i<=m;i++){
        x=qread(); y=qread();
        ins(x^1,y); ins(y^1,x);
    }
    for(int i=2;i<=(n<<1^1);i++)if(!dfn[i]) tarjan(i);
    for(int i=1;i<=cnt;i++)if(color[e[i].from]!=color[e[i].to]) qins(color[e[i].from],color[e[i].to]);
    for(int i=1;i<=n;i++){
        if(color[i<<1]==color[i<<1^1]) return puts("IMPOSSIBLE"),0;
        int p=pd(color[i<<1]),q=pd(color[i<<1^1]);
        if(!p&&!q) return puts("IMPOSSIBLE"),0;
        if(p&&q) ans[i]='?';
        else if(p) ans[i]='N';
        else if(q) ans[i]='Y';
    }
    for(int i=1;i<=n;i++) printf("%c",ans[i]);
    return 0;
}
View Code

 bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列——hash+map

这道题 转2进制后求前缀和,前缀和的每位都减去第一位,如果有两个前缀和 i 和 j 相同的话,那么i+1~j这一段的k种颜色出现次数一样多

这道题有单独的题解QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define LL unsigned long long
const int M=2e5+7,P=233;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,ans;
int d[M][35];
std::map<LL,int>q;
int find(int x){
    LL sum=0;
    for(int i=2;i<=k;i++) sum=sum*P+1LL*d[x][i];
    if(!q[sum]&&sum) q[sum]=x;
    return q[sum];
}
int main(){
    n=read(); k=read();
    for(int i=1;i<=n;i++){
        int now=0,x=read();
        for(;x;x>>=1) d[i][++now]=x&1;
        for(int j=1;j<=k;j++) d[i][j]+=d[i-1][j];
    }
    for(int i=1;i<=n;i++){
        for(int j=2;j<=k;j++) d[i][j]-=d[i][1];
        ans=std::max(ans,i-find(i));
    }printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1718: [Usaco2006 Jan] Redundant Paths 分离的路径——边双连通分量缩点求出叶子数

#include<cstdio>
#include<cstring>
#include<cstring>
#include<algorithm>
using std::min;
const int M=1e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,f[5*M];
int dfn[M],low[M],last[M],stk[M],top;
int color[M],hc,T;
int first[M],cnt=1,star[M],sum=1;
struct node{int from,to,next;}e[5*M],q[5*M];
void ins(int a,int b){e[++cnt]=(node){a,b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
void insq(int a,int b){q[++sum]=(node){a,b,star[a]}; star[a]=sum;}
void insertq(int a,int b){insq(a,b); insq(b,a);}
void tarjan(int x){
    low[x]=dfn[x]=++T;
    stk[++top]=x; last[x]=top;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(f[i^1]) continue; f[i]=1;
        if(!dfn[now]) tarjan(now),low[x]=min(low[x],low[now]);
        else if(!color[now]) low[x]=min(low[x],dfn[now]);
    }
    if(low[x]==dfn[x]) for(hc++;top>=last[x];top--) color[stk[top]]=hc;
}
int in[M],vis[M],ans;
int main(){
    int x,y;
    n=read(); m=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),insert(x,y);
    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    for(int i=2;i<=cnt;i+=2) 
    if(color[e[i].from]!=color[e[i].to]) in[color[e[i].from]]++,in[color[e[i].to]]++;
    for(int i=1;i<=hc;i++) if(in[i]==1) ans++;
    printf("%d\n",(ans+1)>>1);
    return 0;
}
View Code

 bzoj 1700: [Usaco2007 Jan]Problem Solving 解题——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
const int M=557,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans=inf,n,m,f[M][M];
int k,s1[M],s2[M];
int main(){
    memset(f,0x3f,sizeof(f));
    n=read(); m=read();
    for(int i=1;i<=m;i++){
        k=read(); s1[i]=s1[i-1]+k;
        k=read(); s2[i]=s2[i-1]+k;
    }
    f[0][0]=0;f[1][1]=1;f[1][0]=2;
    for(int k=2;k<=m;k++){
        for(int i=1;i<=k;i++)if(s1[k]-s1[k-i]<=n)
        for(int j=0;j<=k-i;j++)if((s1[k]-s1[k-i])+(s2[k-i]-s2[k-i-j])<=n)
        f[k][i]=std::min(f[k][i],f[k-i][j]+1);
        for(int i=1;i<=m;i++)if(s2[k]-s2[k-i]<=n)f[k][0]=min(f[k][0],f[k][i]+1);
    }
    ans=f[m][0]+1;
    for(int i=1;i<=m;i++) if(s2[m]-s2[m-i]<=n) ans=min(ans,f[m][i]+2);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1776: [Usaco2010 Hol]cowpol 奶牛政坛——树的直径QAQ

可以证明一个结论 一棵树的直径必然存在一条过深度最深的点

所以我们可以求出每种颜色最深的点 然后其他点和他求一波lca算答案就可以了

这样的复杂度是nlogn的 

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=3e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int rt,n,k,c[M],mx[M],id[M];
int first[M],cnt;
struct node{int to,next;}e[M];
int f[M][32],fa[M],dep[M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void dfs(int x){//printf("[%d]\n",x);
    for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        dep[now]=dep[x]+1;
        f[now][0]=x;
        if(dep[now]>mx[c[now]]) mx[c[now]]=dep[now],id[c[now]]=now;
        dfs(now);
    }
}
int find(int x,int y){
    if(dep[x]<dep[y]) std::swap(x,y);
    int d=dep[x]-dep[y];
    for(int i=0;(1<<i)<=d;i++) if((1<<i)&d) x=f[x][i];
    if(x==y) return x;
    for(int i=30;i>=0;i--)
     if((1<<i)<=dep[x]&&f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
int ans[M];
int main(){
    int x,y;
    n=read(); k=read();
    for(int i=1;i<=n;i++){
        c[i]=read(); fa[i]=read();
        if(fa[i]) ins(fa[i],i);
        else rt=i;
    }
    dep[rt]=1; dfs(rt);
    for(int i=1;i<=n;i++){
        int lca=find(i,id[c[i]]);
        ans[c[i]]=std::max(ans[c[i]],dep[i]+dep[id[c[i]]]-2*dep[lca]);
    }
    for(int i=1;i<=k;i++) printf("%d\n",ans[i]);
    return 0;
}
View Code

 bzoj 1778: [Usaco2010 Hol]Dotp 驱逐猪猡——高斯消元+概率dp(待填QAQ

 

bzoj 3126: [Usaco2013 Open]Photo——单调队列优化dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
using std::max;
const int M=250007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,x,y;
int l[M],r[M],f[M];
int q[M],ql=1,qr;
int main(){
    n=read(); m=read();
    for(int i=1;i<=n+1;i++) r[i]=i-1;
    for(int i=1;i<=m;i++){
        x=read(); y=read();
        r[y]=min(r[y],x-1);
        l[y+1]=max(l[y+1],x);
    }
    for(int i=n;i;i--) r[i]=min(r[i],r[i+1]);
    for(int i=2;i<=n+1;i++) l[i]=max(l[i],l[i-1]);
    f[qr=1]=0;
    for(int i=1;i<=n+1;i++){
        for(int k=r[i-1]+1;k<=r[i];k++){
            while(ql<=qr&&f[q[qr]]<=f[k]) qr--;
            q[++qr]=k;
        }
        while(ql<=qr&&q[ql]<l[i]) ql++;
        if(ql>qr) f[i]=-inf;
        else f[i]=f[q[ql]]+1;
    }
    if(f[n+1]>=0) printf("%d\n",f[n+1]-1);
    else printf("-1\n");
    return 0;
}
View Code

 当然这道题也有差分约束的写法QAQ——其实是硬水过去的QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using std::queue;
const int M=250007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
bool f=false;
int ans,n,m;
int first[M],cnt;
struct node{int to,next,w;}e[5*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
int dis[M],vis[M];
struct pos{int dis,id;};
bool operator <(pos a,pos b){return a.dis>b.dis;};
std::priority_queue<pos>q;
void spfa(){
    memset(dis,0x3f,sizeof(dis));
    q.push((pos){0,0});
    dis[0]=0; vis[0]=1;
    while(!q.empty()){
        pos x=q.top(); q.pop();
        for(int i=first[x.id];i;i=e[i].next){
            int now=e[i].to;
            if(dis[now]>dis[x.id]+e[i].w){
                ans++; if(ans>300000) return void(f=true);
                dis[now]=dis[x.id]+e[i].w;
                if(!vis[now]) vis[now]=1,q.push((pos){dis[now],now});
            }
        }
        vis[x.id]=0;
    }
}
int main(){
    int l,r;
    n=read(); m=read();
    for(int i=1;i<=m;i++) l=read(),r=read(),ins(l-1,r,1),ins(r,l-1,-1);
    for(int i=1;i<=n;i++) ins(i-1,i,1),ins(i,i-1,0);
    spfa();
    if(f) printf("-1\n");
    else printf("%d\n",dis[n]);
    return 0;
}
View Code

bzoj 1731: [Usaco2005 dec]Layout 排队布局——差分约束

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
const int M=1e3+7,N=1e5+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,ml,md,h[M],vis[M];
int x,y,w,dis[M];
int first[M],cnt;
struct node{int to,next,w;}e[N];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
std::queue<int>q;
bool f=false;
void spfa(){
    memset(dis,0x3f,sizeof(dis));
    q.push(1); dis[1]=0; 
    vis[1]=1; h[1]=1;
    while(!q.empty()){
        int x=q.front(); q.pop(); 
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(dis[now]>dis[x]+e[i].w){
                dis[now]=dis[x]+e[i].w;
                if(!vis[now]){
                    vis[now]=1; q.push(now);
                    h[now]++; if(h[now]==n){f=true; return ;}
                }
            }
        }
        vis[x]=0;
    }
}
int main(){
    n=read(); ml=read(); md=read();
    for(int i=1;i<=ml;i++) x=read(),y=read(),w=read(),ins(x,y,w);
    for(int i=1;i<=md;i++) x=read(),y=read(),w=read(),ins(y,x,-w);
    for(int i=1;i<n;i++) ins(i+1,i,0);
    spfa();
    if(f) printf("-1\n");
    else if(dis[n]==inf) printf("-2\n");
    else printf("%d\n",dis[n]);
    return 0;
}
View Code

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

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
using std::max;
const int M=1e5+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,c,ans,mn;
int h[M],f[M][107];
int main(){
    n=read(); c=read();
    for(int i=1;i<=n;i++) h[i]=read();
    memset(f,0x3f,sizeof(f));
    for(int i=h[1];i<=100;i++) f[1][i]=(h[1]-i)*(h[1]-i);
    for(int k=2;k<=n;k++){
        mn=inf;
        for(int i=h[k-1];i<max(h[k-1],h[k]);i++) mn=min(mn,f[k-1][i]-c*i);
        for(int i=h[k];i<=100;i++){
            mn=min(mn,f[k-1][i]-c*i);
            f[k][i]=mn+c*i+(h[k]-i)*(h[k]-i);
        }
        mn=inf;
        for(int i=100;i>=h[k];i--){
            if(i>=h[k-1]) mn=min(mn,f[k-1][i]+c*i);
            f[k][i]=min(f[k][i],mn-c*i+(h[k]-i)*(h[k]-i));
        }
    }
    ans=inf;
    for(int i=1;i<=100;i++) ans=min(ans,f[n][i]);
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1755: [Usaco2005 qua]Bank Interest-.....

#include<cstdio>
#include<cstring>
#include<algorithm>
double R,M;
int y;
int main(){
    scanf("%lf %lf %d",&R,&M,&y);
    for(int i=1;i<=y;i++) M=M*(1+R/100);
    printf("%d\n",(int)M);
    return 0;
}
View Code

 bzoj 2200: [Usaco2011 Jan]道路和航线

1——spfa+SLF优化QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=3e4+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
bool f=false;
int n,nr,np,S;
int first[M],cnt;
struct node{int to,next,w;}e[7*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
int dis[M],vis[M];
int q[M],head,tail=1;
void spfa(){
    memset(dis,0x3f,sizeof(dis));
    dis[S]=0; vis[S]=1;
    q[head]=S;
    while(head!=tail){
        int x=q[head++]; if(head>M) head=0;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(dis[now]>dis[x]+e[i].w){
                dis[now]=dis[x]+e[i].w;
                if(!vis[now]){
                    vis[now]=1;
                    if(dis[now]<=dis[q[head]]){
                        head--;
                        if(head<0) head=M;
                        q[head]=now;
                    }
                    else{q[tail++]=now; if(tail>M) tail=0;}
                }
            }
        }
        vis[x]=0;
    }
    for(int i=1;i<=n;i++) 
        if(dis[i]>=inf) printf("NO PATH\n");
        else printf("%d\n",dis[i]);
}
int main(){
    int x,y,w;
    n=read(); nr=read(); np=read(); S=read();
    for(int i=1;i<=nr;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    for(int i=1;i<=np;i++) x=read(),y=read(),w=read(),ins(x,y,w);
    spfa();
    return 0;
}
View Code

 2——dfs染色+拓扑+dijkstra

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=3e4+7,inf=0x3f3f3f3f;
char buf[88*M],*ptr=buf-1;
int read(){
    int ans=0,f=1,c=*++ptr;
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=*++ptr;}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=*++ptr;}
    return ans*f;
}
bool flag=false;
int n,nr,np,S;
int first[M],cnt;
struct node{int to,next,w;}e[5*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
int color[M],hc;
void dfs(int x){
    color[x]=hc;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!color[now]) dfs(now);
    }
}
int sum,star[M];
struct pos{int from,to,next,w;}q[5*M];
void insq(int a,int b,int w){q[++sum]=(pos){a,b,star[a],w}; star[a]=sum;}
int f[M],vis[M];
void find(int x){
    vis[x]=f[color[x]]=n+1;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!vis[now]) find(now);
    }
}
int k,dis[M],wh[M],mark[5*M];
struct QAQ{
    int d,id;
    bool operator <(const QAQ& x)const{return x.d<d;}
};
std::priority_queue<QAQ>qu[M];
std::queue<int>Q;
int in[M];
void find_w(int x){
    vis[x]=k;
    for(int i=star[x];i;i=q[i].next){
        int now=color[q[i].to];
        dis[q[i].to]=std::min(dis[q[i].to],dis[x]+q[i].w);
        qu[now].push((QAQ){dis[q[i].to],q[i].to});
        if(!--in[now]) Q.push(now);
    }
    for(int i=first[x];i;i=e[i].next)if(!mark[i]){
        int now=e[i].to;
        if(vis[now]!=k) find_w(now);
    }
}
int main(){
    fread(buf,1,sizeof(buf),stdin);
    int x,y,w;
    n=read(); nr=read(); np=read(); S=read();
    for(int i=1;i<=nr;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    for(int i=1;i<=n;i++)if(!color[i]) hc++,wh[hc]=i,dfs(i);
    for(int i=1;i<=np;i++) x=read(),y=read(),w=read(),ins(x,y,w),mark[cnt]=1,insq(x,y,w);
    memset(dis,0x3f,sizeof(dis)); dis[S]=0;
    for(int i=1;i<=sum;i++) if(f[color[q[i].from]]&&f[color[q[i].to]]) in[color[q[i].to]]++;
    Q.push(color[S]); qu[color[S]].push((QAQ){0,S});
    while(!Q.empty()){
        int x=Q.front(); Q.pop(); k++;
        while(!qu[x].empty()){
            QAQ p=qu[x].top(); qu[x].pop();
            if(dis[p.id]<p.d) continue;
            for(int i=first[p.id];i;i=e[i].next)if(!mark[i]){
                int now=e[i].to; 
                if(dis[now]>dis[p.id]+e[i].w) dis[now]=dis[p.id]+e[i].w,qu[x].push((QAQ){dis[now],now});
            }
        }
        find_w(wh[x]);
    }
    for(int i=1;i<=n;i++) 
        if(dis[i]>=inf) printf("NO PATH\n");
        else printf("%d\n",dis[i]);
    return 0;
}
View Code

 bzoj 1774: [Usaco2009 Dec]Toll 过路费——(改)floyd

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
using std::max;
const int M=357;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,map[M][M],h[M],ans[M][M];
struct node{int id,h;}q[M];
bool cmp(node a,node b){return a.h<b.h;}
void floyd(){
    memset(ans,0x3f,sizeof(ans));
    std::sort(q+1,q+1+n,cmp);
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
          map[i][j]=min(map[i][j],map[i][q[k].id]+map[q[k].id][j]);
          ans[i][j]=min(ans[i][j],map[i][j]+max(max(h[i],h[j]),q[k].h));
    }
}
int main(){
    int x,y,w;
    n=read(); m=read(); k=read();
    memset(map,0x3f,sizeof(map));
    for(int i=1;i<=n;i++) h[i]=q[i].h=read(),q[i].id=i;
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),map[x][y]=map[y][x]=min(map[x][y],w);
    floyd();
    for(int i=1;i<=k;i++) x=read(),y=read(),printf("%d\n",ans[x][y]);
    return 0;
}
View Code

 bzoj 1575: [Usaco2009 Jan]气象牛Baric——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using std::min;
const int M=107,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,f[M][M];
int v[M],star[M],mid[M][M],last[M];
int main(){
    n=read(); k=read();
    for(int i=1;i<=n;i++) v[i]=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<i;j++) star[i]+=2*abs(v[i]-v[j]);
        for(int j=i+1;j<=n;j++) last[i]+=2*abs(v[i]-v[j]);
        for(int j=i+1;j<=n;j++) for(int k=i+1;k<j;k++) mid[i][j]+=abs(2*v[k]-v[i]-v[j]);
    }
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=n;i++){
        f[i][1]=star[i];
        for(int j=2;j<=i;j++)
        for(int k=j-1;k<i;k++) f[i][j]=min(f[i][j],f[k][j-1]+mid[k][i]);
    }
    int ansh=inf,ans=inf;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
        if(f[i][j]+last[i]<=k){
            if(ansh>j) ansh=j,ans=f[i][j]+last[i];
            else if(j==ansh) ans=min(ans,f[i][j]+last[i]);
        }
    printf("%d %d\n",ansh,ans);
    return 0;
}
View Code

 bzoj 1783: [Usaco2010 Jan]Taking Turns——博弈dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
const int M=750007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,id;
LL f[M],g[M],v[M];
int main(){
    n=read(); id=n+1;
    for(int i=1;i<=n;i++) v[i]=read();
    for(int i=n;i>=1;i--){
        f[i]=g[id]+v[i];
        g[i]=f[id];
        if(f[i]>=f[id]) id=i;
    }
    printf("%lld %lld\n",f[id],g[id]);
    return 0;
}
View Code

 bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——大根堆+小根堆+贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
const int M=3e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int f[2*M],cnt,cost,k,n,c,ans;
struct pos{
    int id,h,ed;
    bool operator <(const pos &x)const{return x.ed<ed;}
};
std::vector<pos>e[M];
std::priority_queue<pos>q1;
struct Q{
    int id,h,ed;
    bool operator <(const Q &x)const{return x.ed>ed;}
};
std::priority_queue<Q>q2;
int main(){
    int v,x,y;
    k=read(); n=read(); c=read();
    for(int i=1;i<=k;i++) x=read(),y=read(),v=read(),e[x].push_back((pos){++cnt,v,y});
    for(int i=1;i<=n;i++){
        while(!q1.empty()){
            pos x=q1.top(); 
            if(x.ed>i) break;
            q1.pop();
            if(f[x.id]) continue;
            f[x.id]=1; cost-=x.h; ans+=x.h; 
        }
        int mx=e[i].size();
        for(int j=0;j<mx;j++){
            q1.push((pos){e[i][j].id,e[i][j].h,e[i][j].ed});
            q2.push((Q){e[i][j].id,e[i][j].h,e[i][j].ed});
            cost+=e[i][j].h;
        }
        while(cost>c){
            Q x=q2.top(); q2.pop();
            if(f[x.id]) continue;
            f[x.id]=1;
            if(cost-c>=x.h){cost-=x.h; continue;}
            int now=cost-c;
            cnt++;
            q1.push((pos){cnt,x.h-now,x.ed});
            q2.push((Q){cnt,x.h-now,x.ed});
            cost=c;
        }
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形——极角排序

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using std::sort;
const int M=2e5+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n;
struct pos{int x,y,wh; double k;}q[M];
bool cmp(pos a,pos b){return a.wh!=b.wh?a.wh<b.wh:a.k>b.k;}
int main(){
    int x,y;
    n=read();
    for(int i=1;i<=n;i++){
        x=read(); y=read();
        q[i].x=x; q[i].y=y;
        if(x) q[i].k=1.0*y/x; else q[i].k=-inf;
        if(x>0&&y>=0) q[i].wh=1;
        else if(x>=0&&y<0) q[i].wh=2;
        else if(x<0&&y<=0) q[i].wh=3;
        else q[i].wh=4;
    }
    LL ans=1LL*n*(n-1)*(n-2)/6;
    sort(q+1,q+1+n,cmp);
    LL sum=1,ly=2;
    for(int i=1;i<=n;i++){
        sum--;
        while(1LL*q[ly].y*q[i].x<1LL*q[i].y*q[ly].x){
            ly++; sum++;
            if(ly>n) ly-=n;
        }
        ans=ans-sum*(sum-1)/2;
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1696: [Usaco2007 Feb]Building A New Barn新牛舍——中位数排序

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using std::sort;
using std::min;
const int M=2e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans,sum,n,x[M],y[M];
struct pos{
    int x,y;
    bool operator <(const pos& h)const{return h.x!=x?h.x<x:h.y<y;}
}q[M];
std::map<pos,bool>vis;
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        x[i]=read(); y[i]=read();
        q[i].x=x[i]; q[i].y=y[i];
    }
    sort(x+1,x+1+n); sort(y+1,y+1+n);
    int x1=x[(n+1)/2],y1=y[(n+2)/2],x2=x[(n+2)/2],y2=y[(n+1)/2];
    if(x1==x2&&y1==y2){
        bool f=false;
        for(int i=1;i<=n;i++)if(q[i].x==x1&&q[i].y==y1){f=true; break;}
        if(!f){
            ans=1;
            for(int i=1;i<=n;i++){
                sum=sum+abs(q[i].x-x1);
                sum=sum+abs(q[i].y-y1);
            }
        }
        else{
            int nx=x1,ny=y1-1;
            for(int i=1;i<=n;i++){
                sum=sum+abs(q[i].x-nx);
                sum=sum+abs(q[i].y-ny);
            }
            ans=1; nx=x1; ny=y1+1;
            int now=0;
            for(int i=1;i<=n;i++){
                now=now+abs(q[i].x-nx);
                now=now+abs(q[i].y-ny);
            }
            if(sum>now) ans=1;
            if(sum==now) ans++;
            nx=x1+1; ny=y1;
            now=0;
            for(int i=1;i<=n;i++){
                now=now+abs(q[i].x-nx);
                now=now+abs(q[i].y-ny);
            }
            if(sum>now) ans=1;
            if(sum==now) ans++;
            now=0;
            nx=x1-1; ny=y1;
            for(int i=1;i<=n;i++){
                now=now+abs(q[i].x-nx);
                now=now+abs(q[i].y-ny);
            }
            if(sum>now) ans=1;
            if(sum==now) ans++;
        }
        printf("%d %d\n",sum,ans);
    }
    else{
        ans=(x2-x1+1)*(y1-y2+1);
        for(int i=1;i<=n;i++){
            if(q[i].x>=x1&&q[i].x<=x2&&q[i].y>=y2&&q[i].y<=y1){
                if(!vis[(pos){q[i].x,q[i].y}]){ans--; vis[(pos){q[i].x,q[i].y}]=1;}
            }
            sum=sum+abs(q[i].x-x1);
            sum=sum+abs(q[i].y-y1);
        }
        printf("%d %d\n",sum,ans);
    }
    return 0;
}
View Code

 bzoj 1590: [Usaco2008 Dec]Secret Message 秘密信息

1. 排序版本 如果A是B的前缀 那么字典序 A<=B<=Ainf  正反做一次就可以了 就是有点慢=_=

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using std::sort;
using std::lower_bound;
using std::upper_bound;
const int M=50007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k;
int ans[M],f[M];
struct pos{
    int id; std::vector<int>s;
    bool operator <(const pos& x)const{return s<x.s;}
}s1[M],s2[M];
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++){
        k=read();
        for(int j=1;j<=k;j++) s1[i].s.push_back(read()),s1[i].id=i;
    }
    for(int i=1;i<=m;i++){
        k=read();
        for(int j=1;j<=k;j++)  s2[i].s.push_back(read()),s2[i].id=i;
    }
    sort(s1+1,s1+1+n); sort(s2+1,s2+1+m);
    for(int i=1;i<=n;i++){
        int lx=lower_bound(s2+1,s2+1+m,s1[i])-s2;
        s1[i].s.push_back(inf);
        int rx=upper_bound(s2+1,s2+1+m,s1[i])-s2;
        s1[i].s.pop_back();
        f[lx]++; f[rx]--;
    }
    for(int i=1;i<=m;i++){
        int lx=upper_bound(s1+1,s1+1+n,s2[i])-s1;
        s2[i].s.push_back(inf);
        int rx=upper_bound(s1+1,s1+1+n,s2[i])-s1;
        s2[i].s.pop_back();
        ans[s2[i].id]=rx-lx;
    }
    int now=0;
    for(int i=1;i<=m;i++){now+=f[i]; ans[s2[i].id]+=now;}
    for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}
View Code

 2. trie版本 记一下每个位置作为多少个串的前缀 以及每个串的终止位置 统计一波就可以了 很快QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=1e6+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,son[M],sum[M],ans[M];
int s[M],c[M][2],cnt;
void insert(int len){
    int rt=0;
    for(int i=1;i<=len;i++){
        if(!c[rt][s[i]]) c[rt][s[i]]=++cnt;
        rt=c[rt][s[i]];
        son[rt]++;
    }
    sum[rt]++;
}
int find(int len){
    int rt=0,ans=0;
    for(int i=1;i<=len;i++){
        if(!c[rt][s[i]]) break;
        rt=c[rt][s[i]];
        if(i==len) ans+=son[rt];
        else ans+=sum[rt];
    }
    return ans;
}
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++){
        k=read();
        for(int j=1;j<=k;j++) s[j]=read();
        insert(k);
    }
    for(int i=1;i<=m;i++){
        k=read();
        for(int j=1;j<=k;j++) s[j]=read();
        printf("%d\n",find(k));
    }
    return 0;
}
View Code

 bzoj 3940: [Usaco2015 Feb]Censoring——another坑QAQ

 

bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操——二分+树形dp+贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::sort;
const int M=2e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,sz[M];
int first[M],cnt,s[M];
struct node{int to,next;}e[2*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
bool cmp(int x,int y){return x>y;}
int ans,mx;
void dfs(int x,int fa){
    sz[x]=0;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now==fa) continue;
        dfs(now,x);
    }
    cnt=0;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now==fa) continue;
        s[++cnt]=sz[now]+1;
    }
    sort(s+1,s+1+cnt,cmp);
    int k=1; 
    s[cnt+1]=s[cnt+2]=s[cnt+3]=0;
    while(s[k]+s[k+1]>mx) ans++,k++;
    sz[x]=s[k];
}
bool check(int ly){
    mx=ly; ans=0;
    dfs(1,-1);
    return ans<=k;
}
int main(){
    int x,y;
    n=read(); k=read();
    for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y);
    int l=1,r=n;
    while(l<r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }printf("%d\n",l);
    return 0;
}
View Code

 bzoj 1693: [Usaco2007 Demo]Asteroids——二分图匹配

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using std::min;
const int M=2e3+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k,cur[M],d[M];
int S,T,ans;
int first[M],cnt=1;
struct node{int to,next,flow;}e[20*M];
void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
std::queue<int>q;
int bfs(){
    memset(d,-1,sizeof(d));
    d[S]=1; q.push(S);
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); 
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||a==0) return a;
    int flow=0,f;
    for(int& i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,min(e[i].flow,a)))>0){
            e[i].flow-=f; e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int main(){
    int x,y;
    n=read(); k=read();
    S=0; T=2*n+1;
    for(int i=1;i<=n;i++) insert(S,i,1);
    for(int i=1;i<=n;i++) insert(i+n,T,1);
    for(int i=1;i<=k;i++) x=read(),y=read(),insert(x,y+n,1);
    while(bfs()){for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf);}
    printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1663: [Usaco2006 Open]赶集——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::sort;
using std::max;
const int M=1e3+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans,n,ly[M][M],f[M];
struct pos{int h,id;}q[M];
bool cmp(pos a,pos b){return a.h<b.h;}
int main(){
    n=read();
    for(int i=1;i<=n;i++) q[i].h=read(),q[i].id=i;
    sort(q+1,q+1+n,cmp);
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ly[i][j]=read();
    for(int i=1;i<=n;i++){
        if(ly[1][q[i].id]<=q[i].h) f[i]=1;
        else f[i]=-inf;
        for(int j=1;j<i;j++)
        if(q[j].h+ly[q[j].id][q[i].id]<=q[i].h) f[i]=max(f[i],f[j]+1);
    }
    for(int i=1;i<=n;i++) ans=max(ans,f[i]); printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草——一类dp问题QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
using std::sort;
const int M=1e3+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,star;
int f1[M][M],f2[M][M],s[M];
int main(){
    n=read(); star=read();
    for(int i=1;i<=n;i++) s[i]=read();
    sort(s+1,s+1+n);
    for(int i=1;i<=n;i++) f1[i][i]=f2[i][i]=n*abs(star-s[i]);
    for(int len=2;len<=n;len++){
        for(int i=1;i<=n-len+1;i++){
            int j=i+len-1,now=n-j+i;
            f1[i][j]=min(f1[i+1][j]+(s[i+1]-s[i])*now,f2[i+1][j]+(s[j]-s[i])*now);
            f2[i][j]=min(f1[i][j-1]+(s[j]-s[i])*now,f2[i][j-1]+(s[j]-s[j-1])*now);
        }
    }printf("%d\n",min(f1[1][n],f2[1][n]));
    return 0;
}
View Code

 bzoj 1594: [Usaco2008 Jan]猜数游戏——二分+线段树

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::sort;
using std::max;
using std::min;
const int M=1e5+7,N=3e6+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int cnt,n,m,lx[M],rx[M],mn[N],sign[N],ll[M],rr[M];
struct pos{int l,r,v;}q[M],s[M];
bool cmp(pos a,pos b){return a.v>b.v;}
void clear(){
    cnt=1;
    memset(mn,0,sizeof(mn));
    memset(sign,0,sizeof(sign));
}
int L,R;
void up(int x){mn[x]=min(mn[x<<1],mn[x<<1^1]);}
void down(int x){
    if(!sign[x]) return ;
    int ls=x<<1,rs=x<<1^1;
    sign[x]=0; sign[ls]=sign[rs]=1;
    mn[ls]=mn[rs]=1;
}
void modify(int x,int l,int r){
    if(L<=l&&r<=R){
        mn[x]=1; sign[x]=1;
        return ;
    }
    down(x);
    int mid=(l+r)>>1;
    if(L<=mid) modify(x<<1,l,mid);
    if(R>mid) modify(x<<1^1,mid+1,r);
    up(x);
}
int push_mn(int x,int l,int r){
    if(L<=l&&r<=R) return mn[x];
    down(x);
    int mid=(l+r)>>1,ans=1;
    if(L<=mid) ans=min(ans,push_mn(x<<1,l,mid));
    if(R>mid) ans=min(ans,push_mn(x<<1^1,mid+1,r));
    return ans;
}
bool check(int k){
    if(!k) return 1;
    clear(); 
    for(int i=1;i<=k;i++) s[i]=q[i];
    sort(s+1,s+1+k,cmp);
    int color=s[1].v; 
    lx[1]=s[1].l; rx[1]=s[1].r;
    ll[1]=lx[cnt],rr[1]=rx[cnt];
    for(int i=2;i<=k;i++){
        if(s[i].v!=color){
            cnt++; color=s[i].v;
            lx[cnt]=s[i].l; rx[cnt]=s[i].r;
            ll[cnt]=lx[cnt]; rr[cnt]=rx[cnt];
        }
        else lx[cnt]=min(lx[cnt],s[i].l),rx[cnt]=max(rx[cnt],s[i].r),ll[cnt]=max(ll[cnt],s[i].l),rr[cnt]=min(rr[cnt],s[i].r);
        if(ll[cnt]>rr[cnt]) return 1;
    }
    for(int i=1;i<=cnt;i++){
        L=ll[i]; R=rr[i];
        if(push_mn(1,1,n)!=0) return 1;
        L=lx[i]; R=rx[i];
        modify(1,1,n);
    }
    return 0;
}
int main(){
    n=read(); m=read();
    for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].v=read();
    int l=1,r=m+1;
    while(l<r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    if(r>m) printf("0\n");
    else printf("%d\n",r);
    return 0;
}
View Code

 bzoj 1583: [Usaco2009 Mar]Moon Mooing 哞哞叫

因为两个函数都是单增的所以维护队列就可以了

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
const int M=4e6+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL num[15][15],c,n;
LL ans[M],cnt,l=1,r=1;
int main(){
    c=read(); n=read();
    for(int i=1;i<=2;i++) for(int j=1;j<=3;j++) num[i][j]=read();
    ans[++cnt]=c;
    LL n1=c*num[1][1]/num[1][3]+num[1][2];
    LL n2=c*num[2][1]/num[2][3]+num[2][2];
    while(cnt<n){
        if(n1<n2){
            if(n1!=ans[cnt]) ans[++cnt]=n1;
            n1=ans[++l]*num[1][1]/num[1][3]+num[1][2];
        }
        else{
            if(n2!=ans[cnt]) ans[++cnt]=n2;
            n2=ans[++r]*num[2][1]/num[2][3]+num[2][2];
        }
    }printf("%lld\n",ans[cnt]);
    return 0;
}
View Code

 bzoj 1716: [Usaco2006 Dec]The Fewest Coins 找零钱——多重背包+完全背包

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::max;
using std::min;
const int M=157,N=30007,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int ans,n,T,m,q[N],id[N],ql,qr,mx;
int v[M],c[M],f[N],ly[N];
int main(){
    //freopen("qwq.out","w",stdout);
    n=read(); T=read();
    for(int i=1;i<=n;i++) v[i]=read(),mx=max(mx,v[i]);
    for(int i=1;i<=n;i++) c[i]=read();
    m=mx*mx+T; for(int i=1;i<=m;i++) f[i]=ly[i]=inf;
    for(int i=1;i<=n;i++){
        for(int j=0;j<v[i];j++){
            ql=1; qr=0;
            for(int k=0,now;(now=k*v[i]+j)<m;k++){
                int h=f[now]-k;
                while(ql<=qr&&q[qr]>=h) qr--;
                while(ql<=qr&&id[ql]<k-c[i]) ql++;
                q[++qr]=h; id[qr]=k;
                f[now]=min(inf,q[ql]+k);
            }
        }
    }
    for(int i=1;i<=n;i++) for(int j=v[i];j<=m;j++) ly[j]=min(ly[j],ly[j-v[i]]+1);
    ans=inf;
    for(int i=T;i<=m;i++) ans=min(ans,f[i]+ly[i-T]);
    printf("%d\n",ans==inf?-1:ans);
    return 0;
}
View Code

 bzoj 1775: [Usaco2009 Dec]Vidgame 电视游戏问题——dp

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::max;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,p[55],k,c[55],w[55];
int f[55][100007]; 
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++){
        p[i]=read(); k=read();
        for(int j=1;j<=k;j++){
            c[j]=read(); w[j]=read();
            for(int s=m;s>=c[j];s--) f[i][s]=max(f[i][s],max(f[i-1][s-c[j]]+w[j],f[i][s-c[j]]+w[j]));
        }
        for(int j=m;j>=p[i];j--) f[i][j]=max(f[i-1][j],f[i][j-p[i]]);
        for(int j=0;j<=p[i]-1;j++) f[i][j]=f[i-1][j];  
    }
    int ans=0; for(int i=0;i<=n;i++) ans=max(ans,f[i][m]); printf("%d\n",ans);
    return 0;
}
View Code

 bzoj 1712: [Usaco2007 China]Summing Sums 加密——矩阵乘法

这道题我们可以发现和(sum)每次都会乘(n-1)  所以单独考虑每一位就可以了 这样复杂度就可以接受了

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
const int M=5e4+7,mod=98765431;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL sum,n,m,v[M];
LL ans[3][3],b[3][3],c[3][3];
void pmod(LL a[3][3],LL b[3][3]){
    memset(c,0,sizeof(c));
    for(int i=1;i<=2;i++) for(int k=1;k<=2;k++)
    for(int j=1;j<=2;j++) c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod+mod)%mod;
    for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) a[i][j]=c[i][j];
}
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++) v[i]=read(),sum=(sum+v[i])%mod;
    ans[1][1]=ans[2][2]=1;
    b[1][1]=-1; b[1][2]=1;
    b[2][1]=0;  b[2][2]=n-1;
    while(m){
        if(m&1) pmod(ans,b);
        pmod(b,b); m>>=1;
    }
    sum=(ans[1][2]*sum)%mod;
    for(int i=1;i<=n;i++) printf("%lld\n",((ans[1][1]*v[i])%mod+sum+mod)%mod);
    return 0;
}
View Code

 bzoj 1916: [Usaco2010 Open]冲浪——dp 

f[i][j]表示到点i失控j次的答案 注意按拓扑序来 从n到1逆着dp就可以了QAQ 拓扑的时候小心点 为此WA了3次QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using std::max;
using std::min;
using std::queue;
const int M=250000,N=100007;
const LL inf=1e18;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,k,vis[N];
LL f[N][15];
int first[N],cnt,in[N];
struct node{int to,next; LL w;}e[2*M];
void ins(int a,int b,LL w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,LL w){ins(a,b,w); ins(b,a,w);}
queue<int>q;
void topsort(int x){
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(vis[now]) continue;
        if(!--in[now]) q.push(now),vis[now]=1;
    }
}
void solve(){
    int x=q.front(); q.pop();
    if(x==n){for(int i=1;i<=k;i++) f[x][i]=-inf; topsort(x); return ;}
    LL mn=inf,mx=-inf;
    for(int j=0;j<=k;j++){
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(!vis[now]) continue;
            if(f[now][j]>=0) mx=max(mx,f[now][j]+e[i].w);
            if(j&&f[now][j-1]>=0) mn=min(mn,f[now][j-1]+e[i].w);
        }
        f[x][j]=mx<0?(mn<0?-inf:mn):(mn<0?mx:min(mx,mn));
    }
    topsort(x);
}
int main(){
    int x,y,w;
    n=read(); m=read(); k=read();
    for(int i=1;i<=m;i++){
        x=read(); y=read(); w=read();
        insert(x,y,w);
        in[x]++;
    }
    for(int i=1;i<=n;i++)if(!in[i]) q.push(i),vis[i]=1;
    while(!q.empty()) solve();
    printf("%lld\n",f[1][k]);
    return 0;
}
View Code


bzoj 2274: [Usaco2011 Feb]Generic Cow Protests——树状数组优化dp

f[i]表示前i个数的方案数 这题本质上就是

这里只要满足前缀和小于i的f[j]就可以辣 这个离散化一下前缀和然后树状数组维护一下就可以辣

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using std::sort;
using std::unique;
using std::lower_bound;
const int M=2e5+7,mod=1e9+9;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL n,s[M];
LL b[M],c[M],cnt;
#define lowbit(x) x&-x
void insert(int x,LL w){
    while(x<=cnt){
        s[x]=(s[x]+w)%mod; 
        x+=lowbit(x);
    }
}
LL query(int x){
    LL sum=0;
    while(x) sum=(sum+s[x])%mod,x-=lowbit(x);
    return sum;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++) b[i]=b[i-1]+read(),c[++cnt]=b[i];
    cnt++; sort(c+1,c+1+cnt); cnt=unique(c+1,c+1+cnt)-c-1;
    for(int i=1;i<=n;i++) b[i]=lower_bound(c+1,c+1+cnt,b[i])-c;
    LL ans=lower_bound(c+1,c+1+cnt,0)-c;
    insert(ans,1);
    for(int i=1;i<=n;i++) ans=query(b[i]),insert(b[i],ans);
    printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 3408: [Usaco2009 Oct]Heat Wave 热浪——最短路

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=1e4+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,S,T,d[M];
int first[M],cnt;
struct node{int to,next,w;}e[2*M];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
struct pos{
    int id,d;
    bool operator <(const pos& x)const{return x.d<d;}
};
std::priority_queue<pos>q;
void dj(){
    memset(d,0x3f,sizeof(d));
    d[S]=0; q.push((pos){S,d[S]});
    while(!q.empty()){
        pos x=q.top(); q.pop();
        if(x.d!=d[x.id]) continue;
        for(int i=first[x.id];i;i=e[i].next){
            int now=e[i].to;
            if(d[now]>d[x.id]+e[i].w) 
            d[now]=d[x.id]+e[i].w,q.push((pos){now,d[now]});
        }
    }
}
int main(){
    int x,y,w;
    n=read(); m=read(); S=read(); T=read();
    for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    dj();printf("%d\n",d[T]);
    return 0;
}
View Code

 bzoj 2274: [Usaco2011 Feb]Generic Cow Protests——树状数组优化dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
const int M=2e5+7,mod=1e9+9;
using std::sort;
using std::lower_bound;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,v[M],x[M],f[M],s[M];
#define lowbit(x) x&-x
void ins(int x,int v){while(x<=n) s[x]=(s[x]+v)%mod,x+=lowbit(x);}
int query(int x){int sum=0; while(x) sum=(sum+s[x])%mod,x-=lowbit(x); return sum;}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        v[i]=v[i-1]+read(); x[i]=v[i];
        if(v[i]>=0) f[i]=1;
    }
    sort(x+1,x+1+n);
    for(int i=1;i<=n;i++) v[i]=lower_bound(x+1,x+1+n,v[i])-x;
    for(int i=1;i<=n;i++){
        f[i]=(f[i]+query(v[i]))%mod;
        ins(v[i],f[i]);
    }printf("%d\n",f[n]);
    return 0;
}
View Code

 bzoj 1740: [Usaco2005 mar]Yogurt factory 奶酪工厂——贪心

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
const LL inf=1e15;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL n,s,k,mn=inf,ans;
int main(){
    n=read(); s=read();
    for(int i=1;i<=n;i++){
        k=read();
        if(k-s*i<mn) mn=k-s*i;
        k=read(); ans=ans+(mn+s*i)*k;
    }printf("%lld\n",ans);
    return 0;
}
View Code

 bzoj 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛——二分答案+网络流

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using std::min;
using std::max;
const int M=557,Max=0x3f3f3f3f;
const LL inf=1e15;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,S,T;
LL tot,s[M][M],c[M],h[M],l,r;
int first[5*M],cnt,cur[5*M];
struct node{int to,next,flow;}e[M*M*2];
void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
std::queue<int>q;
LL d[5*M];
int bfs(){
    memset(d,-1,sizeof(d));
    d[S]=0; q.push(S);
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now);
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||!a) return a;
    int f,flow=0;
    for(int &i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){
            e[i].flow-=f; e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
bool check(LL k){
    S=0; T=2*n+1; cnt=1;
    memset(first,0,sizeof(first));
    for(int i=1;i<=n;i++) insert(S,i,c[i]),insert(i+n,T,h[i]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)if(s[i][j]<=k) insert(i,j+n,Max);
    LL sum=0;
    while(bfs()){
        for(int i=0;i<=T;i++) cur[i]=first[i];
        sum+=dfs(S,Max);
    }
    return sum>=tot;
}
int main(){
    int x,y,w;
    n=read(); m=read();
    for(int i=1;i<=n;i++) c[i]=read(),h[i]=read(),tot+=c[i];
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)if(i!=j) s[i][j]=inf;
    for(int i=1;i<=m;i++){
        x=read(); y=read(); w=read();
        s[x][y]=s[y][x]=min(s[x][y],1LL*w);
    }
    for(int k=1;k<=n;k++) for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++) s[i][j]=min(s[i][j],s[i][k]+s[k][j]);
    r=1e15;
    while(l<r){
        LL mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    if(r==1e15) puts("-1");
    else printf("%lld\n",r);
    return 0;
}
View Code

 

posted @ 2017-08-10 07:00  友人Aqwq  阅读(493)  评论(3编辑  收藏  举报