zoukankan      html  css  js  c++  java
  • 8.3-8.7 usaco

    summary:38

    vijos1002:青蛙跳河。

    dp+压缩。距离大于100可以直接%100.然后数据范围小了很多可以dp了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int f[100000];
    int a[105];
    bool vis[100000];
    int main(){
    	int l,s,t,m;
    	scanf("%d%d%d%d",&l,&s,&t,&m);
    	rep(i,1,m) scanf("%d",&a[i]);
    	sort(a+1,a+m+1);
    	if(s==t){
    		int ans=0;
    		rep(i,1,m) if(!(a[i]%s)) ans++;
    		printf("%d
    ",ans);return 0;
    	}
    	int tmp,cnt=0;
    	rep(i,1,m){
    		if((tmp=a[i]-a[i-1])>100) vis[cnt+=100]=1;
    		else vis[cnt+=tmp]=1;
    	}
    	rep(i,0,cnt+t) f[i]=100;f[0]=0;
    	rep(i,0,cnt+t) rep(j,s,t) if(i>=j) f[i]=min(f[i],f[i-j]+vis[i]);
    	int ans=105;
    	rep(i,cnt,cnt+t) ans=min(ans,f[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    vijos1843:货车运输

    最大生成树+lca。然而链剖太久没打WA了很久。id和idx容易混淆注意。是最大生成树森林处理一下,将边的权值弄到点的权值上。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define lson x<<1,l,m
    #define rson x<<1|1,m+1,r
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=20005;
    const int maxn=100005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int dist,from,to;edge *next;
    	bool operator<(const edge &rhs)const{
    	  return dist>rhs.dist;}
    };
    edge e[maxn],edges[maxn<<1],*pt=edges,*head[nmax];
    int fa[nmax],n,m,pre[nmax],son[nmax],size[nmax],dep[nmax],tp[nmax],id[nmax],idx[nmax],w[nmax],sum[nmax<<2];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++;
    }
    int find(int x){
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void dfs(int x){
    	size[x]=1;
    	qwq(x) if(o->to!=pre[x]){
    		int to=o->to;pre[to]=x;dep[to]=dep[x]+1;w[to]=o->dist;
    		dfs(to);size[x]+=size[to];
    		if(!son[x]||size[to]>size[son[x]]) son[x]=to; 
    	}
    }
    void DFS(int x,int top){
    	id[++id[0]]=x;idx[x]=id[0];tp[x]=top;
    	if(son[x]) DFS(son[x],top);
    	qwq(x) if(!idx[o->to]) DFS(o->to,o->to);
    }
    void build(int x,int l,int r){
    	if(l==r) {
    		sum[x]=w[id[l]];return ;
    	}
    	int m=(l+r)>>1;build(lson);build(rson);sum[x]=min(sum[x<<1],sum[x<<1|1]);
    }
    int query(int tl,int tr,int x,int l,int r){
    	if(tl<=l&&tr>=r) return sum[x];
    	int m=(l+r)>>1;int ans=inf;
    	if(tl<=m) ans=min(ans,query(tl,tr,lson));
    	if(tr>m) ans=min(ans,query(tl,tr,rson));
    	return ans;
    }
    int qmax(int a,int b){
    	if(find(a)!=find(b)) return -1;
    	int ans=inf;
    	while(tp[a]!=tp[b]){
    		if(dep[tp[a]]>dep[tp[b]]) swap(a,b);
    		ans=min(ans,query(idx[tp[b]],idx[b],1,1,n));
    		b=pre[tp[b]];
    	}
    	if(dep[a]>dep[b]) swap(a,b);
    	if(idx[a]==idx[b]) return ans;
    	ans=min(ans,query(idx[a]+1,idx[b],1,1,n));
    	return ans;
    }
    int main(){
    	n=read(),m=read();
    	rep(i,1,m) {
    		edge &o=e[i];
    		o.from=read(),o.to=read(),o.dist=read();
    	}
    	
    	sort(e+1,e+m+1);
    	rep(i,1,n) fa[i]=i;
    	rep(i,1,m){
    		edge &o=e[i];
    		int ta=find(o.from),tb=find(o.to);
    		if(ta!=tb){
    			add(o.from,o.to,o.dist);
    			fa[ta]=tb;
    		}
    	}
    	
    	clr(son,0);clr(idx,0);id[0]=0;
    	rep(i,1,n) if(!pre[i]) dep[i]=0,dfs(i);
    	rep(i,1,n) if(!idx[i]) DFS(i,i);
    	
    	build(1,1,n);
    	int Q=read(),u,v;
    	rep(i,1,Q){
    		u=read(),v=read();
    		printf("%d
    ",qmax(u,v));
    	}
    }
    

    bzoj1650:

    二分答案+贪心判断。和noip2015day2t1差不多。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=50005;
    int a[nmax],N,M,L;
    bool check(int x){
    	int ans=0,pre=0;
    	rep(i,1,N) {
    		if(a[i]-a[pre]<x) ans++;
    		else pre=i;
    	}
    	if(ans<=M) return true;
    	return false;
    }
    int main(){
    	L=read(),N=read(),M=read();
    	rep(i,1,N) a[i]=read();
    	sort(a+1,a+N+1);
    	int l=0,r=L,mid,ans=0;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)) ans=mid,l=mid+1;
    		else r=mid-1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1648:

    边数点数少直接暴力dfs

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1005;
    const int maxn=10005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to;edge *next;
    };
    edge edges[maxn],*pt=edges,*head[nmax];
    int a[nmax],ans[nmax];
    bool vis[nmax];
    void add(int u,int v){
    	pt->to=v;pt->next=head[u];head[u]=pt++;
    }
    void dfs(int x){
    	vis[x]=true;ans[x]++;
    	qwq(x) if(!vis[o->to]) dfs(o->to);
    }
    int main(){
    	int K=read(),N=read(),M=read(),u,v;
    	rep(i,1,K) a[i]=read();
    	rep(i,1,M) u=read(),v=read(),add(u,v);
    	rep(i,1,K) clr(vis,false),dfs(a[i]);
    	int res=0;
    	rep(i,1,N) if(ans[i]==K) res++;
    	printf("%d
    ",res);
    	return 0;
    }
    

    bzoj1646:

    简单bfs;

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define clr(x,c) memset(x,c,sizeof(x))
    const int nmax=200005;
    int q[nmax],dist[nmax];
    bool vis[nmax];
    int main(){
    	int n,k;
    	scanf("%d%d",&n,&k);
    	int l=1,r=1;
    	clr(vis,false);vis[n]=true;
    	dist[n]=0;
    	q[r]=n;
    	while(l<=r){
    		int x=q[l];l++;
    		if(x==k){
    			printf("%d
    ",dist[x]);return 0;
    		}
    		if(x-1>=0&&!vis[x-1]) q[++r]=x-1,vis[x-1]=true,dist[x-1]=dist[x]+1;
    		if(x+1<=200000&&!vis[x+1]) q[++r]=x+1,vis[x+1]=true,dist[x+1]=dist[x]+1;
    		if(x+x<=200000&&!vis[x+x]) q[++r]=x+x,vis[x+x]=true,dist[x+x]=dist[x]+1;
    	}
    	return 0;
    }
    

    bzoj1644:

    bfs。不知道为什么我这样子写WA了。。。放一下代码求指点。。挖坑有空再写。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    char s[105];
    bool map[105][105];
    int f[105][105],from[105][105];
    queue<int>q,Q;
    int xx[5]={0,0,0,1,-1};
    int yy[5]={0,1,-1,0,0};
    int main(){
    	int n,sa,sb,ta,tb;scanf("%d",&n);
    	rep(i,1,n){
    		scanf("%s",s+1);
    		rep(j,1,n) {
    			map[i][j]=s[j]=='x'?0:1;
    		    if(s[j]=='A') sa=i,sb=j;
    		    else if(s[j]=='B') ta=i,tb=j;
    		}
    	}
    	clr(f,0x7f);
    	f[sa][sb]=0;
    	q.push(sa);Q.push(sb);
    	int x,y,tx,ty;
    	while(!q.empty()){
    		x=q.front(),y=Q.front();q.pop();Q.pop();
    		rep(i,1,4){
    			tx=x+xx[i],ty=y+yy[i];
    			if(tx<=0||ty<=0||tx>n||ty>n||!map[tx][ty]) continue;
    			if(from[x][y]==i||x==sa&&y==sb) {
    				if(f[x][y]<f[tx][ty])
    			      q.push(tx),Q.push(ty),f[tx][ty]=f[x][y],from[tx][ty]=i;
    			}
    			else  if(f[x][y]<f[tx][ty]-1)
    			   q.push(tx),Q.push(ty),f[tx][ty]=f[x][y]+1,from[tx][ty]=i;
    		}
    	}
    	printf("%d
    ",f[ta][tb]);
    	return 0;
    }
    /*
    5
    ..Bx.
    .xxA.
    ...x.
    .x...
    ..x..*/
    

    bzoj1643:

    O(n^3)暴力,然后第四个数可以推出来。。因为写过一道搜索+剪枝有一个剪枝类似这样子所以会。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int a[105];
    int main(){
    	int n,u,temp,orz,ans=0;
    	scanf("%d",&n);
    	int tmp=(int)sqrt(n)+1;
    	rep(i,0,tmp) a[i]=i*i;
    	rep(i,0,tmp) {
    		rep(j,0,tmp) if(a[i]+a[j]<=n){
    			rep(k,0,tmp) if((u=a[i]+a[j]+a[k])<=n){
    				temp=n-u,orz=sqrt(temp);
    				if(orz*orz==temp) ans++;
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1641:

    floyed即可。。。然而一看到题目就二话不说二分答案+暴力dfs(总是觉得应该可以卡时过去。然而还是tle了。。、不过这种做法应该是对的吧

    /*#include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=305;
    const int maxn=25005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge *next;
    	bool flag;
    };
    edge edges[maxn],*pt=edges,*head[nmax];
    int N,M,Q;
    bool vis[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    }
    bool dfs(int x,int t){
    	vis[x]=true;
    	if(x==t) return true;
    	qwq(x) if(!vis[o->to]&&o->flag){
    		if(dfs(o->to,t)) return true;
    	}
    	return false;
    }
    bool check(int x,int s,int t){
    	rep(i,1,N) qwq(i) if(o->dist<=x) o->flag=true;else o->flag=false;
    	clr(vis,false);
    	if(dfs(s,t)) return true;
    	return false;
    }
    int main(){
    	N=read(),M=read(),Q=read();
    	int u,v,d,sum=0;
    	rep(i,1,M) u=read(),v=read(),d=read(),add(u,v,d),sum=max(sum,d);
    	rep(i,1,Q) {
    		u=read(),v=read();
    		int l=0,r=sum,ans=-1,mid;
    	    while(l<=r){
    		   mid=(l+r)>>1;
    		   if(check(mid,u,v)) ans=mid,r=mid-1;
    		   else l=mid+1;
    	   }
    	   printf("%d
    ",ans);
    	}
    }*/
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=305;
    const int maxn=25005;
    const int inf=0x7f7f7f7f;
    int dist[nmax][nmax];
    int main(){
    	int N=read(),M=read(),Q=read(),u,v,d;
    	clr(dist,0x7f);
    	rep(i,1,M) u=read(),v=read(),d=read(),dist[u][v]=d;
    	rep(k,1,N) rep(i,1,N) rep(j,1,N) if(dist[i][k]!=inf&&dist[k][j]!=inf)
    	  dist[i][j]=min(dist[i][j],max(dist[i][k],dist[k][j]));
    	rep(i,1,Q) {
    		u=read(),v=read();
    		if(dist[u][v]==inf) printf("-1
    ");
    		else printf("%d
    ",dist[u][v]);
    	}
    	return 0;
    }
    

    bzoj1640:

    直接模拟。。。然而没有看清题意WA了唉。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    const int nmax=2005;
    int a[nmax],ans[nmax];
    char c[5];
    int main(){
    	int n;scanf("%d",&n);
    	rep(i,1,n){
    		scanf("%s",c);
    		a[i]=c[0]-'A';
    	}
    	int l=1,r=n,tmp;
    	rep(k,1,n){
    		if(a[l]<a[r]) ans[k]=a[l],l++;
    		else if(a[l]>a[r]) ans[k]=a[r],r--;
    		else{
    			for(int i=l,j=r;i<=j;i++,j--){
    				if(a[i]<a[j]){
    					tmp=l;break;
    				}else if(a[i]>a[j]){
    					tmp=r;break;
    				}else if(i==j){
    					tmp=l;break;
    				}
    			}
    			ans[k]=a[tmp];
    			tmp==l?l++:r--;
    		}
    	}
    	rep(i,1,n){
    		putchar('A'+ans[i]);
    		if(i%80==0) putchar('
    ');
    	}
    	return 0;
    }
    /*
    10
    A
    C
    D
    E
    F
    B
    E
    D
    C
    B
    */
     
    

    bzoj1639:

    二分答案+贪心判断。这种模拟总有感觉自己会写WA,怀疑自己写错。但是只要用模拟一下数据的运算过程还是很容易判断写法的对错的。这也是模拟的调法吧。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=100005;
    const int inf=0x7f7f7f7f;
    int N,M,a[nmax];
    bool check(int x){
    	int ans=0,cur=1,tmp;
    	while(1){
    		tmp=a[cur];
    		if(tmp>x) return false;
    		while(tmp<=x&&cur<=N) cur++,tmp+=a[cur];
    		ans++;
    		if(cur>N) break;
    	}
    	if(ans<=M) return true;
    	return false;
    }
    int main(){
    	N=read(),M=read();
    	rep(i,1,N) a[i]=read();
    	int l=0,r=inf,mid,ans=0;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1638:

    dfs。不会做,orz了hzwer(我原本的做法求方案数又是抱着应该可以卡过去的想法暴力dfs。。。stopstopstop小搜怡情爆搜伤身啊。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define qaq(x) for(edge *o=h[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5005;
    const int maxn=50005;
    const int inf=0x7f7f7f7f;
    bool in[nmax];
    int s[maxn],t[maxn];
    int f[nmax],dp[nmax];
    struct edge{
    	int to;edge *next;
    };
    edge edges[maxn],*pt=edges,*head[nmax];
    edge e[maxn],*p=e,*h[nmax];
    void add(int u,int v){
    	pt->to=v;pt->next=head[u];head[u]=pt++;
    }
    void adde(int u,int v){
    	p->to=v;p->next=h[u];h[u]=p++;
    }
    void dfs(int x){
    	if(!head[x]) {
    		dp[x]=1;return ;
    	}
    	qwq(x){
    		if(!dp[o->to]) dfs(o->to);
    		dp[x]+=dp[o->to];
    	}
    }
    void DFS(int x){
    	if(!h[x]) {
    		f[x]=1;return ;
    	}
    	qaq(x){
    		if(!f[o->to]) DFS(o->to);
    		f[x]+=f[o->to];
    	}
    }
    int main(){
    	int N=read(),M=read(),u,v;
    	rep(i,1,M) u=read(),v=read(),add(u,v),adde(v,u),in[v]=true,s[i]=u,t[i]=v;
    	rep(i,1,N) if(!in[i]) dfs(i);
    	DFS(N);
    	int ans=0;
    	rep(i,1,M) ans=max(ans,dp[t[i]]*f[s[i]]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1637:

    1就+1,0就-1,然后找乱搞就可以了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=50005;
    struct node{
    	int cur,x;
    	bool operator<(const node&rhs)const{
    	  return cur<rhs.cur;}
    };
    node nodes[nmax];
    int sum[nmax],ll[nmax+nmax],rr[nmax+nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) nodes[i].x=read(),nodes[i].cur=read();
    	sort(nodes+1,nodes+n+1);
    	rep(i,1,n) {
    		node&o=nodes[i];
    		if(o.x) sum[i]=sum[i-1]+1;
    		else sum[i]=sum[i-1]-1;
    		if(!ll[sum[i]+n]) ll[sum[i]+n]=i;
    		else rr[sum[i]+n]=i;
    	}
    	int ans=0;
    	rep(i,0,n+n){
    		if(!rr[i]) continue;
    		ans=max(ans,nodes[rr[i]].cur-nodes[ll[i]+1].cur);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1636:

    多次求区间最大最小差值。ST和线段树都可以搞。没写过ST写一下还是挺好写的。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    char s[100];
    void print(int x){
    	int cur=0;
    	if(!x) {
    		putchar('0');putchar('
    ');
    		return;
    	}
    	while(x){
    		s[++cur]=x%10+'0',x/=10;
    	}
    	dwn(i,cur,1) putchar(s[i]);
    	putchar('
    ');
    }
    const int nmax=50005;
    int a[nmax],f[nmax][20],g[nmax][20];
    int main(){
    	int N=read(),Q=read(),u,v;
    	rep(i,1,N) a[i]=read(),f[i][0]=g[i][0]=a[i];
    	for(int k=1;(1<<k)<=N;k++)
    	  for(int i=1;i+(1<<k)-1<=N;i++)
    	    f[i][k]=max(f[i][k-1],f[i+(1<<k-1)][k-1]),g[i][k]=min(g[i][k-1],g[i+(1<<k-1)][k-1]);
    	rep(i,1,Q){
    		u=read(),v=read();
    		int tmp;
    		for(tmp=0;(1<<tmp)<=v-u+1;tmp++);tmp--;
    		print(max(f[u][tmp],f[v-(1<<tmp)+1][tmp])-min(g[u][tmp],g[v-(1<<tmp)+1][tmp]));
    	}
    	return 0;
    }
    

    bzoj1635:

    差分序列!!!感觉好高大上的东西。就是可以区间内加减一个数。然后就可以啦。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=10005;
    int ans[nmax];
    struct node{
    	int x,y;
    	bool operator<(const node&rhs)const{
    	  return x<rhs.x||x==rhs.x&&y<rhs.y;}
    };
    node nodes[nmax];
    int main(){
    	int N=read(),I=read(),H=read(),M=read(),u,v;
    	rep(i,1,M) {
    		node&o=nodes[i];
    		o.x=read(),o.y=read();
    		if(o.x>o.y) swap(o.x,o.y);
    	}
    	sort(nodes+1,nodes+M+1);
    	rep(i,1,M){
    		if(nodes[i].x==nodes[i-1].x&&nodes[i].y==nodes[i-1].y) continue;
    		ans[nodes[i].x+1]--;ans[nodes[i].y]++;
    	}
    	rep(i,1,N) printf("%d
    ",(ans[i]+=ans[i-1])+H);printf("
    ");
    	return 0;
    }

    bzoj1634:

    贪心。对于AB判断A前B后或者A后B前哪一种更优可以推出表达式。那么久可以确定顺序了。以点破面?。。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    const int nmax=100005;
    struct node{
    	int w,t,num;
    	bool operator<(const node&rhs)const{
    	  return rhs.w*t>w*rhs.t;}
    };
    node nodes[nmax];
    int main(){
    	int N;scanf("%d",&N);
    	rep(i,1,N) scanf("%d%d",&nodes[i].w,&nodes[i].t),nodes[i].num=i;
    	sort(nodes+1,nodes+N+1);
    	ll sum=0,ans=0;
    	rep(i,1,N) ans+=sum*nodes[i].t<<1,sum+=nodes[i].w;
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    bzoj1632:

    bfs。多加一维来乱搞(然而我一直调不出来。。。挖坑。啊我为什么bfs总是WA啊。。。

    bzoj1631:

    两遍spfa就可以了。。。将边反过来存储就又变成单源最短路了。。以前见过。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define qaq(x) for(edge *o=h[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();int f=1;
    	while(!isdigit(c)){
    		if(c=='-') f=-1;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f*x;
    }
    const int nmax=1005;
    const int maxn=100005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge*next;
    };
    edge edges[maxn],*pt=edges,*head[nmax];
    edge e[maxn],*p=e,*h[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    }
    void adde(int u,int v,int d){
    	p->to=v;p->dist=d;p->next=h[u];h[u]=p++;
    }
    queue<int>q;
    int dist[nmax],dis[nmax];
    bool inq[nmax];
    void spfa(int t){
    	clr(inq,false);inq[t]=1;
    	clr(dist,0x7f);dist[t]=0;
    	q.push(t);
    	while(!q.empty()){
    		int x=q.front();q.pop();inq[x]=false;
    		qwq(x) if(dist[o->to]>dist[x]+o->dist){
    			dist[o->to]=dist[x]+o->dist;
    			if(!inq[o->to]) q.push(o->to),inq[o->to]=true;
    		}
    	}
    }
    void SPFA(int t){
    	clr(inq,false);inq[t]=1;
    	clr(dis,0x7f);dis[t]=0;
    	q.push(t);
    	while(!q.empty()){
    		int x=q.front();q.pop();inq[x]=false;
    		qaq(x) if(dis[o->to]>dis[x]+o->dist){
    			dis[o->to]=dis[x]+o->dist;
    			if(!inq[o->to]) q.push(o->to),inq[o->to]=true;
    		}
    	}
    }
    int main(){
    	int N=read(),M=read(),T=read(),u,v,d;
    	rep(i,1,M){
    		u=read(),v=read(),d=read();
    		add(u,v,d);adde(v,u,d);
    	}
    	spfa(T);SPFA(T);
    	int ans=-1;
    	rep(i,1,N) ans=max(ans,dist[i]+dis[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1630:

    这可是道背包dp神题啊。挖坑似乎可以前缀和优化+滚动数组。。。然而我只会滚动数组。(防止mle。好劲啊这是。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1e5+5;
    const int maxn=1e3+5;
    const int mod=1e6;
    int dp[nmax],cnt[maxn];
    int main(){
    	int T=read(),A=read(),S=read(),B=read(),u;
    	rep(i,1,A) u=read(),cnt[u]++;
    	dp[0]=1;
    	rep(i,1,T) dwn(j,B,1) rep(k,1,cnt[i]) {
    		if(j<k) break;
    		dp[j]=(dp[j]+dp[j-k])%mod;
    	}
    	int ans=0;
    	rep(i,S,B) ans=(ans+dp[i])%mod;
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1629:

    贪心。。AB谁前谁后可以判断。和1634是同一种类型题。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=50005;
    const int inf=0x7f7f7f7f;
    struct node{
    	int w,t;
    	bool operator<(const node&rhs)const{
    	  return max(-t,w-rhs.t)<max(-rhs.t,rhs.w-t);}
    };
    node nodes[nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) nodes[i].w=read(),nodes[i].t=read();
    	sort(nodes+1,nodes+n+1);
    	int ans=-inf,sum=0;
    	rep(i,1,n) ans=max(ans,sum-nodes[i].t),sum+=nodes[i].w;
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1628:

    单调栈!边界没有处理好!!!注意边界。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=50005;
    int a[nmax],s[nmax];
    int main(){
    	int N=read(),W=read(),u,v;
    	rep(i,1,N) u=read(),a[i]=read();
    	int r=0,ans=0;
    	rep(i,1,N){
    		while(r&&s[r]>a[i]) r--;
    		if(s[r]!=a[i]) ans++;
    		s[++r]=a[i];
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1627:

    简单bfs。。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();int f=1;
    	while(!isdigit(c)){
    		if(c=='-') f=-1;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f*x;
    }
    const int nmax=1005;
    const int orz=500;
    bool on[nmax][nmax],vis[nmax][nmax];
    int dist[nmax][nmax];
    struct node{
    	int x,y;
    	node(int x,int y):x(x),y(y){}
    };
    queue<node>q;
    int xx[5]={0,0,0,1,-1};
    int yy[5]={0,1,-1,0,0};
    int main(){
    	int ta=read(),tb=read(),N=read(),u,v,d;
    	ta+=orz,tb+=orz;
    	clr(vis,false);clr(on,true);
    	rep(i,1,N) u=read(),v=read(),on[u+orz][v+orz]=false;
    	q.push(node(orz,orz));vis[orz][orz]=true;
    	while(!q.empty()){
    		node t=q.front();q.pop();
    		rep(i,1,4){
    			int tx=t.x+xx[i],ty=t.y+yy[i];
    			if(tx&&ty&&tx<=1000&&ty<=1000&&!vis[tx][ty]&&on[tx][ty]) {
    				vis[tx][ty]=true;dist[tx][ty]=dist[t.x][t.y]+1;
    				q.push(node(tx,ty));
    				if(tx==ta&&ty==tb){
    					printf("%d
    ",dist[tx][ty]);
    					return 0;
    				}
    			}
    		}
    	}
    	return 0;
    }
    

    bzoj1626:

    最小生成树。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1005;
    const int maxn=1000005;
    int fa[nmax],xi[nmax],yi[nmax];
    struct edge{
    	int from,to;double dist;
    	bool operator<(const edge&rhs)const{
    	  return dist<rhs.dist;}
    };
    edge edges[maxn];
    int find(int x){
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    int main(){
    	int N=read(),M=read(),u,v,ta,tb;
    	rep(i,1,N) xi[i]=read(),yi[i]=read();
    	rep(i,1,N) fa[i]=i;
    	rep(i,1,M){
    		u=read(),v=read();
    		ta=find(u),tb=find(v);
    		if(ta!=tb) fa[ta]=tb;
    	}
    	int cnt=0;
    	rep(i,1,N-1) rep(j,i+1,N) {
    		edge &o=edges[++cnt];
    		o.from=i,o.to=j;
    		o.dist=sqrt((double)(xi[i]-xi[j])*(xi[i]-xi[j])+(double)(yi[i]-yi[j])*(yi[i]-yi[j]));
    	}
    	sort(edges+1,edges+cnt+1);
    	//rep(i,1,cnt) printf("%d %d %lf
    ",edges[i].from,edges[i].to,edges[i].dist);
    	double ans=0;int res=M;
    	rep(i,1,cnt){
    		ta=find(edges[i].from);tb=find(edges[i].to);
    		if(ta!=tb) fa[ta]=tb,ans+=edges[i].dist,res++;
    		if(res==N-1) break;
    	}
    	printf("%.2lf
    ",ans);
    	return 0;
    }
    

    bzoj1625:

    背包dp。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=3500;
    const int maxn=13000;
    int w[nmax],c[nmax];
    int dp[maxn];
    int main(){
    	int N=read(),M=read();
    	rep(i,1,N) w[i]=read(),c[i]=read();
    	rep(i,1,N) dwn(j,M,w[i]) dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
    	printf("%d
    ",dp[M]);
    	return 0;
    }
    

    bzoj1624:

    floyed。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=105;
    const int maxn=10005;
    int dist[nmax][nmax];
    int ans[maxn];
    int main(){
    	int N=read(),M=read();
    	rep(i,1,M) ans[i]=read();
    	rep(i,1,N) rep(j,1,N) dist[i][j]=read();
    	rep(k,1,N) rep(i,1,N) rep(j,1,N) 
    	  dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
    	int res=0;
    	rep(i,1,M-1) res+=dist[ans[i]][ans[i+1]];
    	printf("%d
    ",res);
    	return 0;
    }
    

    bzoj1623:

    贪心。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=50005;
    int a[nmax];
    int main(){
    	int N=read(),M=read(),D=read(),L=read();
    	rep(i,1,N) a[i]=read();
    	sort(a+1,a+N+1);
    	int ans=0;
    	rep(i,1,N){
    		if(a[i]-ans/M*D>=L) ans++;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1622:

    乱搞。。(这种模拟题我总是很虚啊。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    const int nmax=1005;
    const int maxn=105;
    char s[nmax][nmax],t[maxn][35];
    int ans[nmax];
    int lena[nmax],lenb[nmax];
    int main(){
    	int N,M;
    	scanf("%d%d",&N,&M);
    	rep(i,1,N) {
    		scanf("%s",s[i]);
    		lena[i]=strlen(s[i]);
    		rep(j,0,lena[i]-1) 
    		  if(s[i][j]<'a') s[i][j]+=32;
    	}
    	rep(i,1,M) {
    		scanf("%s",t[i]);
    		lenb[i]=strlen(t[i]);
    		rep(j,0,lenb[i]-1)
    		  if(t[i][j]<'a') t[i][j]+=32;
    	}
    	rep(i,1,N) rep(j,1,M) {
    		int p=0,pt=0;
    		while(p<lena[i]&&pt<lenb[j]){
    			if(s[i][p]==t[j][pt]) pt++;
    			p++;
    		}
    		if(pt==lenb[j]) ans[i]++;
    	}
    	rep(i,1,N) printf("%d
    ",ans[i]);
    	return 0;
    }
    

    bzoj1621:

    递归。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    int n,K;
    int dfs(int x){
    	if((x+K)%2) return 1;
    	if(x<=K) return 1;
    	return dfs((x+K)/2)+dfs((x-K)/2);
    }
    int main(){
    	n=read(),K=read();
    	printf("%d
    ",dfs(n));
    	return 0;
    }
    

    bzoj1620:

    二分答案+贪心判断。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=100005;
    const int inf=0x7f7f7f7f;
    int N,M,a[nmax];
    bool check(int x){
    	int ans=0,cur=1,tmp;
    	while(1){
    		tmp=a[cur];
    		if(tmp>x) return false;
    		while(tmp<=x&&cur<=N) cur++,tmp+=a[cur];
    		ans++;
    		if(cur>N) break;
    	}
    	if(ans<=M) return true;
    	return false;
    }
    int main(){
    	N=read(),M=read();
    	rep(i,1,N) a[i]=read();
    	int l=0,r=inf,mid,ans=0;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1618:

    背包dp。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=60005;
    const int maxn=105;
    const int inf=0x7f7f7f7f;
    int w[maxn],c[maxn];
    int f[nmax];
    int main(){
    	int n=read(),h=read();
    	rep(i,1,n) w[i]=read(),c[i]=read();
    	clr(f,0x7f);f[0]=0;
    	rep(i,1,n) rep(j,0,h) if(f[j]!=inf) f[j+w[i]]=min(f[j+w[i]],f[j]+c[i]);
    	int ans=inf;
    	rep(i,h,h+5005) ans=min(ans,f[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1617:

    区间dp。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int x;
    int read(){
    	x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=2505;
    const int inf=0x7f7f7f7f;
    int cost[nmax],dp[nmax];
    int main(){
    	int n=read(),m=read();
    	rep(i,1,n) cost[i]=read(),cost[i]+=cost[i-1];
    	clr(dp,0x7f);dp[0]=0;
    	rep(i,1,n) rep(j,0,i-1) dp[i]=min(dp[i],dp[j]+cost[i-j]+m+m);
    	printf("%d
    ",dp[n]-m);
    	return 0;
    }
    

    bzoj1616:

    多加一维然后dp转移即可。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=105;
    const int maxn=20;
    int dp[maxn][nmax][nmax],a[nmax][nmax];
    char s[nmax];
    int xx[5]={0,0,0,1,-1};
    int yy[5]={0,1,-1,0,0};
    int main(){
    	int n=read(),m=read(),T=read();
    	rep(i,1,n){
    		scanf("%s",s);
    		rep(j,1,m) a[i][j]=s[j-1]=='.'?1:0;
    	}
    	int sa=read(),ta=read(),sb=read(),tb=read();
    	dp[0][sa][ta]=1;
    	rep(i,1,T) rep(j,1,n) rep(k,1,m) {
    		if(a[j][k]) {
    			rep(o,1,4){
    				int tx=j+xx[o],ty=k+yy[o];
    				if(tx&&ty&&tx<=n&&ty<=m&&a[tx][ty]) dp[i][j][k]+=dp[i-1][tx][ty];
    			}
    		}else dp[i][j][k]=0;
    	}
    	printf("%d
    ",dp[T][sb][tb]);
    	return 0;
    }
    

    bzoj1615:

    乱搞。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();int f=1;
    	while(!isdigit(c)){
    		if(c=='-') f=-1;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x*f;
    }
    const int nmax=205;
    int x[nmax],y[nmax];
    double ans[nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) x[i]=read(),y[i]=read();
    	int cnt=0;bool f=false;
    	rep(i,1,n) rep(j,1,n) if(i!=j){
    		if(x[i]==x[j]) f=true;
    		else ans[++cnt]=(double)(y[i]-y[j])/(x[i]-x[j]);
    	}
    	sort(ans+1,ans+cnt+1);
    	int res=0;
    	if(cnt) res++;
    	rep(i,2,cnt) if(ans[i]!=ans[i-1]) res++;
    	if(f) res++;
    	printf("%d
    ",res);
    	return 0;
    }
    

    bzoj1612:

    spfa求路径最小值。。。都是差不多的啦。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1005;
    const int maxn=10005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge *next;
    };
    edge edges[maxn],*pt=edges,*head[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++;
    }
    struct node{
    	int x,k;
    	node(int x,int k):x(x),k(k){}
    };
    queue<node>q;
    int dist[nmax][nmax];
    bool inq[nmax][nmax];
    void spfa(int K,int n){
    	clr(dist,0x7f);dist[1][0]=0;
    	clr(inq,false);inq[1][0]=true;
    	q.push(node(1,0));
    	while(!q.empty()){
    		node oo=q.front();q.pop();inq[oo.x][oo.k]=false;
    		qwq(oo.x){
    			int to=o->to;
    			if(dist[to][oo.k]>max(dist[oo.x][oo.k],o->dist)) {
    				dist[to][oo.k]=max(dist[oo.x][oo.k],o->dist);
    				if(!inq[to][oo.k]){
    					q.push(node(to,oo.k));inq[to][oo.k]=true;
    				}
    			}
    			if(oo.k>=K) continue;
    			if(dist[to][oo.k+1]>dist[oo.x][oo.k]){
    				dist[to][oo.k+1]=dist[oo.x][oo.k];
    				if(!inq[to][oo.k+1]){
    					q.push(node(to,oo.k+1));inq[to][oo.k+1]=true;
    				}
    			}
    		}
    	}
    	if(dist[n][K]==inf) printf("-1
    ");
    	else printf("%d
    ",dist[n][K]);
    	return ;
    }
    int main(){
    	int n=read(),m=read(),p=read(),u,v,d;
    	rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d);
    	spfa(p,n);
    	return 0;
    }
    

    bzoj1612:

    暴力dfsQAQ。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define qaq(x) for(edge *o=h[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=105;
    const int maxn=4505;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to;edge *next;
    };
    edge edges[maxn],*pt=edges,*head[nmax];
    edge e[maxn],*p=e,*h[nmax];
    int ans[nmax];
    bool vis[nmax];
    void add(int u,int v){
    	pt->to=v;pt->next=head[u];head[u]=pt++;
    	p->to=u;p->next=h[v];h[v]=p++;
    }
    void dfs(int x){
    	qwq(x) if(!vis[o->to]) ans[o->to]++,vis[o->to]=true,dfs(o->to);
    }
    void DFS(int x){
    	qaq(x) if(!vis[o->to]) ans[o->to]++,vis[o->to]=true,DFS(o->to);
    }
    int main(){
    	int n=read(),m=read(),u,v;
    	rep(i,1,m) u=read(),v=read(),add(u,v);
    	rep(i,1,n) {
    		clr(vis,false);dfs(i);
    	}
    	rep(i,1,n){
    		clr(vis,false);DFS(i);
    	}
    	int res=0;
    	rep(i,1,n) if(ans[i]==n-1) res++;
    	printf("%d
    ",res);
    	return 0;
    }
    

    bzoj1611:

    对于每个点,能转移到该点必定没有被炸,那么可以利用这一点性质在bfs时转移!。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=305;
    const int inf=0x7f7f7f7f;
    int map[nmax][nmax],dist[nmax][nmax];
    bool vis[nmax][nmax];
    struct node{
    	int x,y;
    	node(int x,int y):x(x),y(y){}
    };
    queue<node>q;
    int xx[5]={0,0,0,1,-1};
    int yy[5]={0,1,-1,0,0};
    int main(){
    	int m=read(),u,v,d;
    	clr(map,0x7f);
    	rep(i,1,m) {
    		u=read(),v=read(),d=read();map[u][v]=min(map[u][v],d);
    		rep(k,1,4) if(u+xx[k]>=0&&v+yy[k]>=0) map[u+xx[k]][v+yy[k]]=min(d,map[u+xx[k]][v+yy[k]]);
    	}
    	if(map[0][0]==inf){
    		printf("0
    ");return 0;
    	}
    	q.push(node(0,0));
    	clr(vis,false);vis[0][0]=true;dist[0][0]=0;
    	while(!q.empty()){
    		node o=q.front();q.pop();
    		rep(i,1,4){
    			int x=o.x,y=o.y,tx=x+xx[i],ty=y+yy[i];
    			if(tx<0||ty<0||map[tx][ty]-1<=dist[x][y]||vis[tx][ty]) continue;
    			if(map[tx][ty]==inf){
    				printf("%d
    ",dist[x][y]+1);return 0;
    			}
    			q.push(node(tx,ty));dist[tx][ty]=dist[x][y]+1;vis[tx][ty]=true;
    		}
    	}
    	printf("-1
    ");
    	return 0;
    }
    

    bzoj4395:

    暴力+bfs。多次bfs就可以了。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=105;
    const int maxn=20005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,too;edge *next;
    };
    edge edges[maxn],*pt=edges,*head[nmax][nmax];
    bool on[nmax][nmax],vis[nmax][nmax];
    void add(int x,int y,int d,int w){
    	pt->to=d;pt->too=w;pt->next=head[x][y];head[x][y]=pt++;
    }
    
    struct node{
    	int a,b;
    	node(int a,int b):a(a),b(b){}
    };
    queue<node>q;
    
    int xx[5]={0,0,0,1,-1};
    int yy[5]={0,1,-1,0,0};
    
    int main(){
    	int n=read(),m=read();
    	rep(i,1,m){
    		int u=read(),v=read(),d=read(),w=read();
    		add(u,v,d,w);
    	}
    	int ans=1,last=1;on[1][1]=true;
    	while(1){
    	  q.push(node(1,1));
    	  clr(vis,0);vis[1][1]=true;
    	  while(!q.empty()){
    		node x=q.front();q.pop();
    		for(edge *o=head[x.a][x.b];o;o=o->next){
    			if(!on[o->to][o->too]) on[o->to][o->too]=true,ans++;
    		}
    		rep(i,1,4){
    			int tx=x.a+xx[i],ty=x.b+yy[i];
    			if(tx&&ty&&tx<=n&&ty<=n){
    				if(on[tx][ty]&&!vis[tx][ty]) 
    				  vis[tx][ty]=true,q.push(node(tx,ty));
    			}
    		}
    	  }
    	  if(last==ans) break;
    	  last=ans;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1318:

    神题。。这种题都不知道怎么想出来的。。。orzhzwer后勉勉强强懂了。。。然而太神了这。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1000015;
    const int inf=0x7f7f7f7f;
    int n,ans=-1,last[nmax],next[nmax],a[nmax];
    ll sum[nmax];
    bool vis[nmax];
    void solve(int x){
    	int len=0,rmax=inf;
    	rep(i,x+1,n) {
    		if(a[i]==1) break;
    		if(!vis[a[i]]) vis[a[i]]=true;
    		else {
    			rmax=i;break;
    		}
    	}
    	dwn(i,x,1){
    		if(a[i]==1&&i!=x) break;
    		rmax=min(rmax,next[i]);
    		len=max(len,a[i]);
    		if(i+len-1<=n&&i+len-1<rmax&&sum[i+len-1]-sum[i-1]==(ll)len*(len+1)/2) ans=max(ans,len); 
    	}
    	rep(i,x+1,n) {
    		if(a[i]==1) break;
    		vis[a[i]]=false;
    	}
    }
    void work(){
    	clr(last,0x7f);
    	dwn(i,n,1) {
    		next[i]=last[a[i]];
    		last[a[i]]=i;
    	}
    	rep(i,1,n) if(a[i]==1) solve(i);
    }
    int main(){
    	n=read();
    	rep(i,1,n) a[i]=read(),sum[i]=sum[i-1]+a[i];
    	work();
    	reverse(a+1,a+n+1);
    	clr(sum,0);
    	rep(i,1,n) sum[i]=sum[i-1]+a[i];
    	work();
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1306:

    搜索+剪枝!。我写了三个剪枝但是tle了。到网上一看然后再加一个剪枝就卡过去了。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    int f[4]={3,1,0,0};
    int ans[9],a[9],res=0,n;
    void dfs(int x,int y){
    	if(ans[x]>a[x]) return ;
    	if(ans[x]+(n-y+1)*3<a[x]) return ;
    	if(x==n) {
    		res++;return ;
    	}
    	if(y==n){
    		int tmp=a[x]-ans[x];
    		if(tmp==2) return ;
    		ans[y]+=f[tmp];
    		dfs(x+1,x+2);
    		ans[y]-=f[tmp];
    	}else{
    		ans[x]+=3;dfs(x,y+1);ans[x]-=3;
    		ans[x]++,ans[y]++,dfs(x,y+1),ans[x]--,ans[y]--;
    		ans[y]+=3;dfs(x,y+1),ans[y]-=3;
    	}
    }
    int main(){
    	n=read();
    	rep(i,1,n) a[i]=read();
    	dfs(1,2);
    	printf("%d
    ",res);
    	return 0;
    }
    

    bzoj1303:

    大于的就+1,小于的就-1,求中位数子串有多少个。。然后乱搞就可以了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=200005;
    const int inf=0x7f7f7f7f;
    int a[nmax],cnt[nmax],sum[nmax];//qi ou
    int main(){
    	int n=read(),m=read(),cur,u;
    	rep(i,1,n){
    		a[i]=read();
    		if(a[i]==m) cur=i;
    		a[i]+=100000;
    	}
    	m+=100000;
    	sum[100000]=1;a[0]=100000;
    	rep(i,1,cur-1){
    		if(a[i]>m) a[i]=a[i-1]+1;
    		else a[i]=a[i-1]-1;
    		if(i%2) cnt[a[i]]++;
    		else sum[a[i]]++;
    	}
    	int ans=0;
    	rep(i,cur,n){
    		if(a[i]>m) a[i]=a[i-1]+1;
    		else if(a[i]==m) a[i]=a[i-1];
    		else a[i]=a[i-1]-1;
    		if(i%2) ans+=sum[a[i]];
    		else ans+=cnt[a[i]];
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    关于项目中的已发现的难点
    怎样与用户有效地沟通以获取用户的真实需求?
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答。
    当下大部分互联网创业公司为什么都愿意采用增量模型来做开发?
    第二次作业
    第一次作业
    第二次博客作业
    第一次博客作业
    第二次博客作业
    第一次博客作业
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5747583.html
Copyright © 2011-2022 走看看