首页 > 代码库 > [Noi2016]区间
[Noi2016]区间
这道题不愧是第一题,真的挺水的.
看到要搞使区间的最大长度和最少长度之差最小,先按长度排序.
要统计某个地方的出现次数,有这么大的数据范围,离散坐标少不了.
排序完之后,选择的区间肯定是连续的一段了,不如二分枚举再加上线段树判定吧...
当然不是这么搞的,搞两个指针前后移动维护最大值>=m的性质即可.
丑丑的代码,不过懒得改了.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<iomanip> #include<algorithm> #include<map> using namespace std; #define LL long long #define FILE "dealing" #define up(i,j,n) for(int i=j;i<=n;++i) #define db double #define ull unsigned long long #define eps 1e-10 #define pii pair<int,int> int read(){ int x=0,f=1,ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} return f*x; } const int maxn=4002200,maxm=20000,mod=(int)(1e9+7+0.1),inf=(int)(2e9); template<class T>bool cmax(T& a,T b){return a<b?a=b,true:false;} template<class T>bool cmin(T& a,T b){return a>b?a=b,true:false;} template<class T>T min(T& a,T& b){return a<b?a:b;} template<class T>T max(T& a,T& b){return a>b?a:b;} int delet[maxn],Max[maxn]; void add(int x,int d){ delet[x]+=d; Max[x]+=d; } void pushdown(int x){ if(delet[x]){ add(x<<1,delet[x]); add(x<<1|1,delet[x]); delet[x]=0; } } void updata(int x){ Max[x]=max(Max[x<<1],Max[x<<1|1]); } int L,R,key; void change(int x,int l,int r){ if(l>R||r<L)return ; if(l>=L&&r<=R){ add(x,key); return ; } int mid=(l+r)>>1; pushdown(x); change(x<<1,l,mid); change(x<<1|1,mid+1,r); updata(x); } int n,m; struct node{int x,y,id;}e[maxn],w[maxn]; bool cmp(node a,node b){return (a.y-a.x)<(b.y-b.x);} pii a[maxn];int val[maxn],N,M,q[maxn][2]; int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read(); up(i,1,n)a[++N].first=e[i].x=read(), a[N].second=i,a[++N].first=e[i].y=read(), a[N].second=i,e[i].id=i; sort(e+1,e+n+1,cmp); sort(a+1,a+N+1); a[0].first=-1; up(i,1,N){ if(a[i].first!=a[i-1].first) val[++M]=a[i].first;//真正权值 if(q[a[i].second][0])q[a[i].second][1]=M; else q[a[i].second][0]=M; } up(i,1,n)w[i].x=q[e[i].id][0],w[i].y=q[e[i].id][1];//排序后hash权值 int left=1,ans=inf; for(int i=1;i<=n;i++){ if(Max[1]<m){ L=w[i].x,R=w[i].y;key=1; change(1,1,M); } while(Max[1]>=m){ cmin(ans,(val[w[i].y]-val[w[i].x])-(val[w[left].y]-val[w[left].x])); L=w[left].x,R=w[left].y,key=-1; change(1,1,M); left++; } } if(ans==inf)printf("-1\n"); else printf("%d\n",ans); return 0; }
[Noi2016]区间
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。