继续昨晚上的绝望……
实在不行了,学习了一个网上的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;
}
原文:http://www.cnblogs.com/zj75211/p/7619709.html