这两题思路与题目都差不多,
我的想法是开一个线段树维护最小值,从后往前找,第一个为0的值一定是最靠前的,返回其位置,将其置为0x3f3f3f3f,然后把这个位置以后的值统统-1,继续下一个循环。
好像只有我用这种思路。。。。。。
poj 2182 ac代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <string>
#include <vector>
//#include <iostream>
using namespace std;
//memset(x,0,sizeof x);
//scanf("%d",&x);
//for(i=0;i<n;i++)
int tree[801000];
int lazy[801000];
int infor[201000];
int build(int l,int r,int now)
{
lazy[now]=0;
if(l==r)
{
scanf("%d",&tree[now]);
scanf("%d",&infor[l]);
return 0;
}
build(l,(l+r)/2,now*2);
build((l+r)/2+1,r,now*2+1);
tree[now]=min(tree[now*2],tree[now*2+1]);
return 0;
}
int finding(int l,int r,int now)
{
if(l==r)
{
tree[now]=0x3f3f3f3f;
return l;
}
if(lazy[now]!=0)
{
tree[now*2]-=lazy[now];tree[now*2+1]-=lazy[now];
lazy[now*2]+=lazy[now];lazy[now*2+1]+=lazy[now];
lazy[now]=0;
}
int mid=(l+r)/2,ans;
if(tree[now*2+1]==0)
ans=finding(mid+1,r,now*2+1);
else
ans=finding(l,mid,now*2);
tree[now]=min(tree[now*2],tree[now*2+1]);
return ans;
}
int change(int l,int r,int now,int ll,int rr)
{
if(ll<=l&&rr>=r)
{
tree[now]--;
lazy[now]++;
return 0;
}
int mid=(l+r)/2;
if(lazy[now]!=0)
{
tree[now*2]-=lazy[now];tree[now*2+1]-=lazy[now];
lazy[now*2]=lazy[now];lazy[now*2+1]=lazy[now];
lazy[now]=0;
}
if(rr<=mid)
change(l,mid,now*2,ll,rr);
else if(ll>=mid+1)
change(mid+1,r,now*2+1,ll,rr);
else
{
change(l,mid,now*2,ll,rr);
change(mid+1,r,now*2+1,ll,rr);
}
tree[now]=min(tree[now*2],tree[now*2+1]);
return 0;
}
int main()
{
int i,j,k,n,m,l;
while(scanf("%d",&n)!=EOF)
{
build(1,n,1);
for(i=1;i<=n;i++)
{
j=finding(1,n,1);
printf("%d ",infor[j]);
change(1,n,1,j,n);
}
printf("\n");
}
return 0;
}
poj 2828代码 注意必须用c++,g++有迷之bug可能过不了
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <string>
#include <vector>
//#include <iostream>
using namespace std;
//memset(x,0,sizeof x);
//scanf("%d",&x);
//for(i=0;i<n;i++)
int tree[801000];
int lazy[801000];
int infor[201000];
int build(int l,int r,int now)
{
lazy[now]=0;
if(l==r)
{
scanf("%d",&tree[now]);
scanf("%d",&infor[l]);
return 0;
}
build(l,(l+r)/2,now*2);
build((l+r)/2+1,r,now*2+1);
tree[now]=min(tree[now*2],tree[now*2+1]);
return 0;
}
int finding(int l,int r,int now)
{
if(l==r)
{
tree[now]=0x3f3f3f3f;
return l;
}
if(lazy[now]!=0)
{
tree[now*2]-=lazy[now];tree[now*2+1]-=lazy[now];
lazy[now*2]+=lazy[now];lazy[now*2+1]+=lazy[now];
lazy[now]=0;
}
int mid=(l+r)/2,ans;
if(tree[now*2+1]==0)
ans=finding(mid+1,r,now*2+1);
else
ans=finding(l,mid,now*2);
tree[now]=min(tree[now*2],tree[now*2+1]);
return ans;
}
int change(int l,int r,int now,int ll,int rr)
{
if(ll<=l&&rr>=r)
{
tree[now]--;
lazy[now]++;
return 0;
}
int mid=(l+r)/2;
if(lazy[now]!=0)
{
tree[now*2]-=lazy[now];tree[now*2+1]-=lazy[now];
lazy[now*2]=lazy[now];lazy[now*2+1]=lazy[now];
lazy[now]=0;
}
if(rr<=mid)
change(l,mid,now*2,ll,rr);
else if(ll>=mid+1)
change(mid+1,r,now*2+1,ll,rr);
else
{
change(l,mid,now*2,ll,rr);
change(mid+1,r,now*2+1,ll,rr);
}
tree[now]=min(tree[now*2],tree[now*2+1]);
return 0;
}
int main()
{
int i,j,k,n,m,l;
while(scanf("%d",&n)!=EOF)
{
build(1,n,1);
for(i=1;i<=n;i++)
{
j=finding(1,n,1);
printf("%d ",infor[j]);
change(1,n,1,j,n);
}
printf("\n");
}
return 0;
}