标签:pop bar ack names als front include tmp lower
继续昨晚上的绝望……
实在不行了,学习了一个网上的AC代码,用map实现的,总算是AC了
代码:
#include<map> 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
struct cannon{
	ll a,d;
	bool operator <(const cannon &b)const{
        return (a<b.a || (a==b.a && d<b.d));
    }
}c[250005];
ll mountain[250005],last,k;
map<ll,ll>f;
int n,m,ans,cnt;
int main(){
	freopen("in.in","r",stdin);
	freopen("mine.out","w",stdout);
	scanf("%d%d%lld",&n,&m,&k);
	for(int i=1;i<=n;i++) scanf("%lld",&mountain[i]);
	for(int i=1;i<=m;i++) scanf("%lld%lld",&c[i].a,&c[i].d);
	sort(c+1,c+m+1);
	for(int i=1;i<=m;i++){
		while(cnt&&c[cnt].d<=c[i].d) cnt--;
		c[++cnt]=c[i];
	}
	last=0;f[0]=0;
    for(int i=1;i<=cnt;i++){
        if(i!=1) last=c[i-1].a;
        //p[i].d>p[i+1].d
        for(ll j=max(last,c[i].a-c[i].d)+1;j<=c[i].a;j++){
            ll t=(j-last-1)/c[i].d+1;
            f[j]=f[max(0ll,j-(c[i].d*t))]+t;
        }
    }
    last=0; int p=0;
    for(int i=n;i>=1;i--){
        while(p<=cnt&&c[p].a<mountain[i]) p++;
        if(p>cnt)break;
        if(p!=1)last=c[p-1].a;
        ll t=(mountain[i]-last-1)/c[p].d+1;
        ll q=f[max(0ll,mountain[i]-(c[p].d*t))]+t;
        if(k>=q)k-=q,++ans;else break;
    }
	printf("%d %lld\n",ans,k);
	return 0;
}
所以对于每个节点,向上最多只会存在一个祖先到它的边权和为k
那么只需dfs遍历时维护到该点的路径,并二分查找是否存在一个祖先到它的距离为k。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 200005
using namespace std;
struct edge{
	int to,val,next;
}e[MAXN*2];
int head[MAXN],sum[MAXN];
int n,rt,k,cnt,ans,ent=1;
void add(int u,int v,int w){
	e[ent]=(edge){v,w,head[u]};
	head[u]=ent++;
}
void binary_search(){
	int tmp=sum[cnt]-k;
	int sub=lower_bound(sum+1,sum+cnt+1,tmp)-sum;
	if(sum[sub]==tmp) ans++;
}
void dfs(int u,int w,int fa){
	cnt++;
	sum[cnt]=sum[cnt-1]+w;
	binary_search();
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==fa) continue;
		dfs(v,e[i].val,u);
	}
	cnt--;
}
int main(){
	scanf("%d%d%d",&n,&rt,&k);
	for(int i=1,a,b,c;i<n;i++){
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c); add(b,a,c);
	}
	dfs(rt,0,0);
	printf("%d",ans);
	return 0;
}
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
queue<int>q;
int cnt[2005]; 
int n,m,ans=0x3f3f3f3f,g,a,b;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,x;i<=n;i++){
		scanf("%d",&x);
		if(!cnt[x]) g++; q.push(x); cnt[x]++;
		while(cnt[q.front()]>1) cnt[q.front()]--,q.pop();
		if(g==m&&q.size()<ans){
			ans=q.size();
			a=i-q.size()+1;
			b=i;
		}
	}
	printf("%d %d",a,b);
	return 0;
}
标签:pop bar ack names als front include tmp lower
原文地址:http://www.cnblogs.com/zj75211/p/7619709.html